Frage

ich beobachtet, dass äußere Klassen Privat innere Klassen Instanzvariablen zugreifen können. Wie ist das möglich? Hier ist ein Beispielcode demonstriert das gleiche:

class ABC{
    class XYZ{
        private int x=10;
    }

    public static void main(String... args){
        ABC.XYZ xx = new ABC().new XYZ();
        System.out.println("Hello :: "+xx.x); ///Why is this allowed??
    }
}

Warum ist dieses Verhalten erlaubt?

War es hilfreich?

Lösung

Die innere Klasse ist nur ein Weg, um sauber einige Funktionen zu trennen, die wirklich auf die ursprüngliche äußeren Klasse gehört. Sie sollen verwendet werden, wenn Sie zwei Anforderungen:

  1. würde Einige Stück Funktionalität in Ihrer äußeren Klasse sein klarsten, wenn es in einer separaten Klasse implementiert wurde.
  2. Auch wenn es in einer separaten Klasse ist, ist die Funktionalität sehr eng mit Art und Weise, dass die äußeren Klasse funktioniert.

diese Anforderungen gegeben, innere Klassen haben vollen Zugriff auf ihre äußeren Klasse. Da sie im Grunde ein Mitglied der äußeren Klasse sind, dann macht es Sinn, dass sie Zugang zu Methoden und Attribute der äußeren Klasse -. Einschließlich Gemeinen

Andere Tipps

Wenn Sie die privaten Mitglieder Ihrer inneren Klasse verstecken, können Sie eine Schnittstelle mit den öffentlichen Member definieren und eine anonyme innere Klasse, die diese Schnittstelle implementiert. Beispiel unten:

class ABC{
    private interface MyInterface{
         void printInt();
    }

    private static MyInterface mMember = new MyInterface(){
        private int x=10;

        public void printInt(){
            System.out.println(String.valueOf(x));
        }
    };

    public static void main(String... args){
        System.out.println("Hello :: "+mMember.x); ///not allowed
        mMember.printInt(); // allowed
    }
}

Die innere Klasse ist (für die Zwecke der Zugangskontrolle) als Teil der enthaltenden Klasse sein. Das bedeutet, vollen Zugriff auf alle Gemeinen.

Die Art und Weise dies umgesetzt wird, ist synthetisches Paket geschützte Methoden: Die innere Klasse wird im selben Paket (ABC $ XYZ) in eine separate Klasse kompiliert werden. Die JVM nicht diesen Grad an Isolation unterstützen direkt, so dass bei der Bytecode-Ebene ABC $ XYZ-Paket-geschützten Methoden haben, die die äußere Klasse verwendet den privaten Methoden / Felder zu erhalten.

Es gibt eine richtige Antwort auf eine andere Frage ähnlich wie diese erscheinen: Warum kann das private Mitglied einer geschachtelten Klasse mit den Methoden der umschließenden Klasse zugegriffen werden?

Es sagt, es gibt eine Definition des privaten Scoping auf JLS - Bestimmung Zugänglichkeit :

  

Ansonsten, wenn das Mitglied oder Konstruktor privat deklariert ist, so wird der Zugriff erlaubt, wenn und nur wenn sie innerhalb des Körpers der Top-Level-Klasse auftritt (§7.6), der die Erklärung des Mitglieds oder Konstruktor umschließt.

Ein IMHO wichtiger Anwendungsfall für innere Klassen ist die Fabrik-Muster. Die umschließenden Klasse kann eine Instanz der inneren Klasse vorbereiten w / o Zugangsbeschränkungen und die Instanz für die Außenwelt übergibt, in dem privaten Zugang geehrt werden.

Im Gegensatz zu abyx die Klasse statische erklärt ändern Einschränkungen Zugriff nicht zu der umgebenden Klasse, wie unten gezeigt. Auch die Zugangsbeschränkungen zwischen statischen Klassen in der gleichen umgebenden Klasse arbeiten. Ich war überrascht ...

class MyPrivates {
    static class Inner1 { private int test1 = 2; }
    static class Inner2 { private int test2 = new Inner1().test1; }

    public static void main(String[] args) {
        System.out.println("Inner : "+new Inner2().test2);
    }
}

Zugriffsbeschränkungen werden auf einer pro Klasse Basis. Es gibt keine Möglichkeit für eine Methode in einer Klasse deklariert nicht in der Lage sein, alle von der Instanz / die Teilnehmer zuzugreifen. Es ist diese liegt nahe, dass innere Klassen auch ungehinderten Zugang zu den Mitgliedern der äußeren Klasse haben und die äußere Klasse hat ungehinderten Zugang zu den Mitgliedern der inneren Klasse.

Durch eine Klasse innerhalb einer anderen Klasse setzen Sie machen es fest an die Umsetzung gebunden, und alles, was Teil der Umsetzung ist, sollte Zugang zu den anderen Teilen haben.

Die Logik hinter inneren Klassen ist, dass, wenn Sie eine innere Klasse in einer äußeren Klasse erstellen, das ist, weil sie ein paar Dinge teilen müssen, und so macht es Sinn für sie in der Lage sein, mehr Flexibilität zu haben, als „normale“ Klassen haben.

Wenn in Ihrem Fall, es macht keinen Sinn für die Klassen der Lage sein, sich gegenseitig die inneren Abläufe zu sehen - was im Grunde bedeutet, dass die innere Klasse einfach eine reguläre Klasse hätte leisten können, können Sie die innere Klasse als static class XYZ erklären . Mit static bedeutet, sie werden nicht Staat teilen (und zum Beispiel new ABC().new XYZ() wird nicht funktionieren, und Sie müssen new ABC.XYZ() verwenden.
Aber wenn das der Fall ist, sollten Sie darüber nachdenken, ob XYZ sollte wirklich eine innere Klasse sein und vielleicht verdient es eine eigene Datei. Manchmal macht es Sinn, eine statische innere Klasse erstellen (zum Beispiel, wenn Sie eine kleine Klasse benötigen, die eine Schnittstelle Ihrer äußeree Klasse implementiert verwendet, und das wird nicht hilfreich sein, anderswo). Aber etwa die Hälfte der Zeit sollte es eine äußere Klasse gemacht worden sind.

Thilo hinzugefügt eine gute für Ihre erste Frage beantworten: „Wie ist das möglich?“. Ich möchte ein bisschen auf der zweiten gestellte Frage erarbeiten: Warum ist dieses Verhalten erlaubt

Für den Anfang, lassen Sie sich einfach vollkommen klar sein, dass dieses Verhalten nicht nur für innere Klassen erlaubt ist per Definition, die nicht-statische verschachtelte Typen sind. Dieses Verhalten ist für alle geschachtelte Typen erlaubt, einschließlich verschachtelter Aufzählungen und Schnittstellen, die statisch sein muss und kann eine umgebende Instanz nicht haben. Grundsätzlich ist das Modell ist eine Vereinfachung bis auf die folgende Erklärung ab:. Nested Code vollen Zugang zum umschließenden Code hat - und umgekehrt

Also, warum dann? Ich denke, ein Beispiel der Punkt besser verdeutlichen.

Denken Sie an Ihren Körper und Ihr Gehirn. Wenn Sie Heroin in den Arm zu injizieren, wird Ihr Gehirn hoch. Wenn die Amygdala Region des Gehirns sehen, was er glaubt, dass eine Bedrohung für Ihre persönliche Sicherheit, sagt eine Wespe zum Beispiel, wird er Ihren Körper in die andere Richtung um und läuft in den Bergen ohne Sie „dachte“ zweimal darüber drehen machen.

So

ist das Gehirn ein untrennbarer Teil des Körpers - und seltsam genug, die andere Art und Weise zu sich um. Mit Zugriffskontrolle zwischen solchen eng verbundenen Unternehmen verlieren ihren Anspruch der Beziehung. Wenn Sie Zugriffskontrolle benötigen, dann müssen Sie die Klassen mehr in wirklich getrennte Einheiten trennen. Bis dahin sind sie die gleiche Einheit. Ein Antrieb Beispiel für weitere Untersuchungen an, wie ein Java

Inner-Klasse wird als Attribut der äußeren Klasse angesehen. Daher keine die innere Klasseninstanz egal Variable privat ist oder nicht, kann Outer Klasse ohne Probleme Zugang ebenso wie seine anderen privaten Attribute Zugriff (Variablen).

class Outer{

private int a;

class Inner{
private int b=0;
}

void outMethod(){
a = new Inner().b;
}
}

Da Ihr main() Methode ist in der ABC-Klasse, die können Zugriff auf seine eigene innere Klasse.

scroll top