Java: nessuna istanza chiusa di tipo Foo è accessibile


314

Ho il codice seguente:

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!");
    }
}

So Thingche non fa nulla, ma il mio programma Hello, World si compila bene senza di esso. Sono solo le mie classi definite che mi mancano.

E si rifiuta di compilare. Arrivo No enclosing instance of type Hello is accessible."alla linea che crea una nuova Cosa. Suppongo sia:

  1. Ho problemi a livello di sistema (in DrJava o nella mia installazione Java) o
  2. Ho dei malintesi di base su come costruire un programma di lavoro in Java.

Qualche idea?


Risposte:


483

static class Thing farà funzionare il tuo programma.

Così com'è, hai Thinguna classe interna, che (per definizione) è associata a una particolare istanza di Hello(anche se non la usa mai o non si riferisce ad essa), il che significa che è un errore dire new Thing();senza avere una particolare Helloistanza in scopo.

Se invece lo dichiari come una classe statica, allora è una classe "nidificata", che non ha bisogno di una particolare Helloistanza.


Questo significa anche che se creo un'istanza di outer class, non-static inner classverrà creato anche se non lo uso da nessuna parte?
5

No. Ogni oggetto di una classe interna deve avere un genitore, ma un genitore può avere un numero qualsiasi di figli incluso 0.
jacobm

92

Hai dichiarato la classe Thingcome classe interna non statica. Ciò significa che deve essere associato a un'istanza diHello classe.

Nel tuo codice, stai provando a creare un'istanza di Thing da un contesto statico. Questo è ciò di cui si lamenta il compilatore.

Ci sono alcune possibili soluzioni. La soluzione da utilizzare dipende da ciò che si desidera ottenere.

  • Spostare Thingfuori dalla Helloclasse.

  • Cambia Thingin una staticclasse nidificata.

    static class Thing
  • Creare un'istanza di Helloprima di creare un'istanza di 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
    }

L'ultima soluzione (una classe nidificata non statica ) sarebbe obbligatoria se qualsiasi istanza di Thingdipendesse da un'istanza Hellofosse significativa. Ad esempio, se avessimo:

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;
        }
    }
    ...
}

qualsiasi tentativo grezzo di creare un oggetto di classe Thing, come in:

Thing t = new Thing(31);

sarebbe problematico, dal momento che non ci sarebbe un enormousvalore ovvio per testare 31 contro di esso. Un'istanza hdella Helloclasse esterna è necessaria per fornire questo h.enormousvalore:

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

Perché non significa a Thingse non ha aHello .

Per ulteriori informazioni sulle classi nidificate / interne: Nested Classes (The Java Tutorials)


La tua risposta è completa e sintetica. Anche se sembra strano (almeno per me), la sintassi è corretta.
Boumbh

Se qualcuno continua a ricevere errori, la sintassi Thing thing1 <<HelloInstantiation>>.new Thing()è la chiave. Ho trascorso alcuni minuti confuso usando la sintassi Thing thing1 new <<HelloInstantiation>>.Thing(). = P
skia.heliou,

1
@ skia.heliou Grazie! Stavo creando una classe di supporto e le variabili statiche (o anche le classi) non solo eliminavano l'ambito, ma spesso sono inefficienti. La necessità di fornire argomenti di runtime rende problematico l'utilizzo di un metodo principale. Era tutto ciò di cui avevo bisogno ed esattamente quello che stavo cercando di trovare.
Carrello abbandonato

25

Bene ... tante buone risposte ma voglio aggiungerne altre. Un breve sguardo alla classe interna in Java-Java ci consente di definire una classe all'interno di un'altra classe e Essere in grado di nidificare le classi in questo modo ha alcuni vantaggi:

  1. Può nascondere (aumenta l'incapsulamento) la classe da altre classi - particolarmente rilevante se la classe viene utilizzata solo dalla classe in cui è contenuta. In questo caso non è necessario che il mondo esterno lo sappia.

  2. Può rendere il codice più gestibile in quanto le classi sono raggruppate logicamente insieme dove sono necessarie.

  3. La classe interna ha accesso alle variabili e ai metodi dell'istanza della sua classe contenitore.

Abbiamo principalmente tre tipi di Inner Classes

  1. Interno locale
  2. Classe interna statica
  3. Classe interna anonima

Alcuni dei punti importanti da ricordare

  • Abbiamo bisogno dell'oggetto class per accedere alla classe interna locale in cui esiste.
  • La classe interna statica accede direttamente allo stesso modo di qualsiasi altro metodo statico della stessa classe in cui esiste.
  • La classe interna anonima non è visibile al mondo esterno così come agli altri metodi o classi della stessa classe (in cui esiste) e viene utilizzata nel punto in cui viene dichiarata.

Proviamo a vedere praticamente i concetti sopra

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!");
    }
 }

}

Spero che questa volontà aiuti tutti. Si prega di fare riferimento per ulteriori informazioni


Miglioramenti suggeriti: denominare MyOuterClass di prima classe, rimuovere i commenti da AnonymousClass.
Noumenon,

9

Thingè una classe interna con una connessione automatica a un'istanza di Hello. Viene visualizzato un errore di compilazione perché non esiste un'istanza Helloper cui collegarsi. Puoi risolverlo più facilmente cambiandolo in una classe nidificata statica che non ha connessioni:

static class Thing

9

Comprendiamolo con il seguente semplice esempio. Ciò accade perché si tratta di una CLASSE INTERNA NON STATICA. Dovresti aver bisogno dell'istanza della classe esterna.

 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");

        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.