web-dev-qa-db-fra.com

Java - Aucune instance englobante de type Foo n'est accessible

J'ai le code suivant:

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

Je sais que Thing ne fait rien, mais mon programme Bonjour, World compile sans problème. Ce ne sont que mes classes définies qui échouent sur moi.

Et il refuse de compiler. Je reçois No enclosing instance of type Hello is accessible." à la ligne qui crée une nouvelle chose. Je devine soit:

  1. J'ai des problèmes au niveau du système (soit dans DrJava ou mon installation Java) ou
  2. J'ai quelques incompréhensions de base sur la façon de construire un programme de travail en Java.

Des idées?

295
coolpapa

static class Thing fera fonctionner votre programme.

En l'état, vous avez Thing en tant que classe interne, qui (par définition) est associée à une instance particulière de Hello (même si elle ne l'utilise jamais ou ne s'y réfère jamais), ce qui signifie une erreur de dire new Thing(); sans avoir une instance particulière de Hello.

Si vous la déclarez en tant que classe statique, il s'agit d'une classe "imbriquée", qui n'a pas besoin d'une instance Hello particulière.

457
jacobm

Vous avez déclaré la classe Thing en tant que classe interne non statique. Cela signifie qu'il doit être associé à une instance de la classe Hello.

Dans votre code, vous essayez de créer une instance de Thing à partir d'un contexte statique. C'est ce dont se plaint le compilateur.

Il y a quelques solutions possibles. La solution à utiliser dépend de ce que vous voulez réaliser.

  • Déplacez Thing de la classe Hello.

  • Changez Thing pour qu'il soit une classe static imbriquée.

    static class Thing
    
  • Créez une instance de Hello avant de créer une instance 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 dernière solution (une classe imbriquée non statique ) serait obligatoire si une instance quelconque de Thing dépendait d'une instance de Hello avoir un sens. Par exemple, si nous avions:

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

toute tentative brute de créer un objet de classe Thing, comme dans:

Thing t = new Thing(31);

serait problématique, car il n'y aurait pas de valeur évidente enormous de tester 31 contre. Une instance h de la classe Hello externe est nécessaire pour fournir cette valeur h.enormous:

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

Parce que cela ne signifie pas un Thing s'il n'a pas de Hello.

Pour plus d'informations sur les classes imbriquées/internes: Classes imbriquées (Les Java Tutorials))

88
helloworld922

Eh bien ... tellement de bonnes réponses mais je veux ajouter plus. Un bref aperçu de la classe Inner en Java- Java nous permet de définir une classe au sein d'une autre classe. La possibilité d'imbriquer des classes de cette manière présente certains avantages:

  1. Il peut masquer (augmenter l'encapsulation) la classe des autres classes - particulièrement pertinent si la classe n'est utilisée que par la classe dans laquelle elle est contenue. Dans ce cas, le monde extérieur n’a nul besoin de le savoir.

  2. Cela peut rendre le code plus facile à gérer car les classes sont regroupées logiquement autour de l'endroit où elles sont nécessaires.

  3. La classe interne a accès aux variables d'instance et aux méthodes de la classe qui la contient.

Nous avons principalement trois types de Inner Classes

  1. Intérieur local
  2. Classe intérieure statique
  3. Classe intérieure anonyme

Quelques points importants à retenir

  • Nous avons besoin de l’objet class pour accéder à la classe locale dans laquelle il existe.
  • La classe statique interne obtient directement accès de la même manière que toute autre méthode statique de la même classe dans laquelle elle existe.
  • Les classes internes anonymes ne sont pas visibles dans le monde externe ainsi que dans les autres méthodes ou classes de la même classe (dans laquelle elle existe) et sont utilisées au point où elles sont déclarées.

Essayons de voir les concepts ci-dessus pratiquement _

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

}
_

J'espère que cela aidera à tout le monde. S'il vous plaît voir plus

24
Rupesh Yadav

Permet de comprendre avec l'exemple simple suivant. Cela est dû au fait qu’il s’agit d’une classe interne non statique. Vous devriez avoir besoin de l'instance de la classe externe.

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

        }
    }
}
9
AZ_

Thing est un classe intérieure avec une connexion automatique à une instance de Hello. Vous obtenez une erreur de compilation car il n'y a pas d'instance de Hello à laquelle s'attacher. Vous pouvez le réparer plus facilement en le changeant en un classe imbriquée statique qui n'a pas de connexion:

static class Thing
9
David Harkness