Java – Geen omsluitende instantie van het type Foo is toegankelijk

Ik heb de volgende code:

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

Ik weet dat Thingniets doet, maar mijn Hello, World-programma compileert prima zonder. Alleen mijn gedefinieerde lessen falen bij mij.

En het weigert te compileren. Ik krijg No enclosing instance of type Hello is accessible."op de regel die een nieuw ding maakt. Ik vermoed een van beide:

  1. Ik heb problemen op systeemniveau (in DrJava of mijn Java-installatie) of
  2. Ik heb een aantal fundamentele misvattingen over hoe een werkend programma in Java moet worden gebouwd.

Enig idee?


Antwoord 1, autoriteit 100%

static class Thinglaat je programma werken.

Zoals het is, heb je Thingals een innerlijke klasse, die (per definitie) is gekoppeld aan een bepaalde instantie van Hello(zelfs als het nooit of ernaar verwijst), wat betekent dat het een fout is om new Thing();te zeggen zonder een bepaalde Hello-instantie in het bereik te hebben.

Als je het in plaats daarvan als een statische klasse declareert, is het een “geneste” klasse, die geen bepaalde Hello-instantie nodig heeft.


Antwoord 2, autoriteit 19%

Je hebt de klasse Thinggedeclareerd als een niet-statische innerlijke klasse. Dat betekent dat het moet worden gekoppeld aan een instantie van de klasse Hello.

In uw code probeert u een instantie van Thingte maken vanuit een statische context. Dat is waar de compiler over klaagt.

Er zijn een paar mogelijke oplossingen. Welke oplossing voor gebruik is afhankelijk van wat u wilt bereiken.

  • Verplaatsen ThingUit de HelloKLASSE.

  • Wijzigen ThingOm een ​​staticgeneste klasse.

    static class Thing
    
  • Maak een instantie van Hellovoordat u een exemplaar van 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
    }
    

De laatste oplossing (een niet-statische geneste klas) zou verplicht zijn als een instantie van Thingafhankelijk is van een exemplaar van Hellowees zinvol. Als we bijvoorbeeld hadden:

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

Elke onbewerkte poging om een ​​object van de klasse Thingte maken, zoals in:

Thing t = new Thing(31);

zou problematisch zijn, omdat er geen voor de hand liggende enormouswaarde zou zijn om 31 tegen te testen. Een instantie hvan de HelloBUITE KLASSE is nodig om dit te verstrekken h.enormouswaarde:

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

Omdat het geen Thingbetekent als het geen Helloheeft.

Voor meer informatie over geneste/innerlijke klassen:
Nested Classes (de Java-tutorials)


Antwoord 3, autoriteit 5%

Nou… zo veel goede antwoorden, maar ik wil er meer aan toevoegen. Een korte blik op Inner class in Java- Java stelt ons in staat om een class binnen een andere class te definiëren en
Het op deze manier kunnen nesten van klassen heeft bepaalde voordelen:

  1. Het kan de klasse verbergen(Het verhoogt de inkapseling)van andere klassen – vooral relevant als de klasse alleen wordt gebruikt door de klasse waarin deze zich bevindt. In dit geval hoeft de buitenwereld er niets van te weten.

  2. Het kan code beter onderhoudbaar makenomdat de klassen logisch zijn gegroepeerd rond waar ze nodig zijn.

  3. De innerlijke klasse heeft toegangtot de instantievariabelen en methoden van de bevattende klasse.

We hebben hoofdzakelijk drie soorten Inner Classes

  1. Lokale innerlijke
  2. Statische innerlijke klasse
  3. Anonieme innerlijke klasse

Enkele belangrijke punten om te onthouden

  • We hebben een klasseobject nodig om toegang te krijgen tot de Lokale Innerlijke Klasse waarin het bestaat.
  • Statische Inner Class krijgt direct toegang, net als elke andere statische methode van dezelfde klasse waarin deze bestaat.
  • Anonymous Inner Class is niet zichtbaar voor de buitenwereld en ook niet voor de andere methoden of klassen van dezelfde klasse (waarin het bestaat) en het wordt gebruikt op het punt waar het wordt gedeclareerd.

Laten we proberen de bovenstaande concepten praktisch te bekijken_

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

Ik hoop dat dit aan iedereen zal helpen. Alsjeblieft Zie voor meer


Antwoord 4, Autoriteit 2%

Thingis een Binnenklasse Met een automatische verbinding met een exemplaar van Hello. U krijgt een compileerfout omdat er geen instantie is van Helloom eraan te bevestigen. Je kunt het het gemakkelijkst repareren door het te veranderen in een statische geneste klasse die geen verbinding heeft:

static class Thing

Antwoord 5, Autoriteit 2%

Laten we het begrijpen met het volgende eenvoudige voorbeeld.
Dit gebeurt omdat dit niet-statische innerlijke klasse is. U moet het exemplaar van de buitenklasse nodig hebben.

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

Antwoord 6

Verklaar het binnen klasse ding als een statisch en het zal zonder problemen werken.

Ik herinner me dat ik hetzelfde probleem heb met de innerlijke klassehond toen ik het als klas Dog {alleen verklaarde. Ik heb hetzelfde probleem zoals je deed. Er waren twee oplossingen :

1- om de binnenklasse hond als statisch te declareren. of

2- Om de innerlijke hond zelf naar een nieuwe klas te verplaatsen.

Dit is het voorbeeld:

openbare klasse ReturnDemo {

public static void main(String[] args) {
    int z = ReturnDemo.calculate(10, 12);
    System.out.println("z = " + z);
    ReturnDemo.Dog dog = new Dog("Bosh", " Doggy");
    System.out.println( dog.getDog());
}
public static int calculate (int x, int y) {
    return x + y;
}
public void print( ) {
    System.out.println("void method");
    return;
}
public String getString() {
    return "Retrun String type value";
}
static class Dog {
private String breed;
private String name;
public Dog(String breed, String name) {
    super();
    this.breed = breed;
    this.name = name;
}
public Dog getDog() {
    // return Dog type;
    return this;
}
public String toString() {
    return "breed" + breed.concat("name: " + name);
}
}

}


Antwoord 7

Vóór Java 14
U moet een statisch trefwoord toevoegen om toegang te krijgen tot klasse Thingvanuit de statische context.

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

Java 14+
Vanaf Java 14 kunt u innerlijke recordklassen gebruiken, deze zijn impliciet statisch. Dus je zou hebben:

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

Other episodes