Java: no se puede acceder a ninguna instancia adjunta del tipo Foo


314

Tengo el siguiente código:

class Hello {
    class Thing {
        public int size;

        Thing() {
            size = 0;
        }
    }

    public static void main(String[] args) {
        Thing thing1 = new Thing();
        System.out.println("Hello, World!");
    }
}

Thingque no hace nada, pero mi programa Hello, World se compila muy bien sin él. Son solo mis clases definidas las que me están fallando.

Y se niega a compilar. Llego No enclosing instance of type Hello is accessible."a la línea que crea una nueva Cosa. Supongo que tampoco:

  1. Tengo problemas a nivel del sistema (ya sea en DrJava o en mi instalación de Java) o
  2. Tengo algunos malentendidos básicos sobre cómo construir un programa de trabajo en Java.

¿Algunas ideas?


posible duplicado de la clase interna
Strelok

Respuestas:


483

static class Thing hará que su programa funcione.

Tal como está, lo tienes Thingcomo una clase interna, que (por definición) está asociada con una instancia particular de Hello(incluso si nunca la usa o se refiere a ella), lo que significa que es un error decir new Thing();sin tener una Helloinstancia particular en alcance.

Si lo declaras como una clase estática, es una clase "anidada", que no necesita una Helloinstancia particular .


¿Esto también significa que si crea una instancia de outer class, non-static inner classtambién se crearía incluso si no lo uso en ningún lado?
Mr5

No. Cada objeto de una clase interna debe tener un padre, pero un padre puede tener cualquier número de hijos, incluido 0.
jacobm

92

Has declarado la clase Thingcomo una clase interna no estática. Eso significa que debe estar asociado con una instancia deHello clase.

En su código, está intentando crear una instancia de Thing un contexto estático. De eso se queja el compilador.

Hay algunas soluciones posibles. Qué solución usar depende de lo que quieras lograr.

  • Mover Thingfuera de la Helloclase.

  • Cambiar Thingpara ser una staticclase anidada.

    static class Thing
  • Cree una instancia de Helloantes de crear una instancia de Thing.

    public static void main(String[] args)
    {
        Hello h = new Hello();
        Thing thing1 = h.new Thing(); // hope this syntax is right, typing on the fly :P
    }

La última solución (una clase anidada no estática ) sería obligatoria si alguna instancia Thingdependiera de una instancia de Helloser significativa. Por ejemplo, si tuviéramos:

public class Hello {
    public int enormous;

    public Hello(int n) {
        enormous = n;
    }

    public class Thing {
        public int size;

        public Thing(int m) {
            if (m > enormous)
                size = enormous;
            else
                size = m;
        }
    }
    ...
}

Cualquier intento en bruto de crear un objeto de clase Thing, como en:

Thing t = new Thing(31);

sería problemático, ya que no habría un enormousvalor obvio para probar 31 en su contra. Es necesaria una instancia hde la Helloclase externa para proporcionar este h.enormousvalor:

...
Hello h = new Hello(30);
...
Thing t = h.new Thing(31);
...

Porque no significa un Thingsi no tiene un Hello.

Para obtener más información sobre clases anidadas / internas: Clases anidadas (los tutoriales de Java)


Su respuesta es integral y sintética. Incluso si se siente extraño (al menos para mí), la sintaxis es correcta.
boumbh

Si alguien sigue recibiendo errores, la sintaxis Thing thing1 <<HelloInstantiation>>.new Thing()es la clave. Pasé unos minutos confundido usando la sintaxis Thing thing1 new <<HelloInstantiation>>.Thing(). = P
skia.heliou

1
@ skia.heliou Gracias! Estaba haciendo una clase auxiliar y las variables estáticas (o incluso clases) no solo eliminan el alcance, sino que a menudo son ineficientes. La necesidad de proporcionar argumentos de tiempo de ejecución hace que sea una molestia usar un método principal. Esto era todo lo que necesitaba y exactamente lo que estaba buscando encontrar.
Carro abandonado el

25

Bueno ... muchas buenas respuestas pero quiero agregar más. Una breve mirada a la clase interna en Java: Java nos permite definir una clase dentro de otra clase y ser capaz de anidar clases de esta manera tiene ciertas ventajas:

  1. Puede ocultar (aumenta la encapsulación) la clase de otras clases, especialmente relevante si la clase solo está siendo utilizada por la clase en la que está contenida. En este caso, no es necesario que el mundo exterior lo sepa.

  2. Puede hacer que el código sea más fácil de mantener ya que las clases se agrupan lógicamente en torno a donde se necesitan.

  3. La clase interna tiene acceso a las variables de instancia y métodos de su clase que contiene.

Tenemos principalmente tres tipos de Inner Classes

  1. Interior local
  2. Clase interna estática
  3. Clase interna anónima

Algunos de los puntos importantes para recordar

  • Necesitamos un objeto de clase para acceder a la clase interna local en la que existe.
  • Se accede directamente a la clase interna estática igual que a cualquier otro método estático de la misma clase en la que existe.
  • La clase interna anónima no es visible para el mundo externo, así como para los otros métodos o clases de la misma clase (en la que existe) y se usa en el punto donde se declara.

Intentemos ver los conceptos anteriores prácticamente_

public class MyInnerClass {

public static void main(String args[]) throws InterruptedException {
    // direct access to inner class method
    new MyInnerClass.StaticInnerClass().staticInnerClassMethod();

    // static inner class reference object
    StaticInnerClass staticInnerclass = new StaticInnerClass();
    staticInnerclass.staticInnerClassMethod();

    // access local inner class
    LocalInnerClass localInnerClass = new MyInnerClass().new LocalInnerClass();
    localInnerClass.localInnerClassMethod();

    /*
     * Pay attention to the opening curly braces and the fact that there's a
     * semicolon at the very end, once the anonymous class is created:
     */
    /*
     AnonymousClass anonymousClass = new AnonymousClass() {
         // your code goes here...

     };*/
 }

// static inner class
static class StaticInnerClass {
    public void staticInnerClassMethod() {
        System.out.println("Hay... from Static Inner class!");
    }
}

// local inner class
class LocalInnerClass {
    public void localInnerClassMethod() {
        System.out.println("Hay... from local Inner class!");
    }
 }

}

Espero que esto ayude a todos. Por favor refiérase para más


Mejoras sugeridas: nombre la primera clase MyOuterClass, elimine los comentarios de alrededor de AnonymousClass.
Noumenon

9

Thinges una clase interna con una conexión automática a una instancia de Hello. Obtiene un error de compilación porque no hay ninguna instancia Hellopara que se adjunte. Puede solucionarlo más fácilmente cambiándolo a una clase anidada estática que no tiene conexión:

static class Thing

9

Vamos a entenderlo con el siguiente ejemplo simple. Esto sucede porque se trata de una CLASE INTERNA NO ESTÁTICA. Debería necesitar la instancia de la clase externa.

 public class PQ {

    public static void main(String[] args) {

        // create dog object here
        Dog dog = new PQ().new Dog();
        //OR
        PQ pq = new PQ();
        Dog dog1 = pq.new Dog();
    }

    abstract class Animal {
        abstract void checkup();
    }

    class Dog extends Animal {
        @Override
        void checkup() {
            System.out.println("Dog checkup");

        }
    }

    class Cat extends Animal {
        @Override
        void checkup() {
            System.out.println("Cat Checkup");

        }
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.