nichtstatische Innere Klasse, this Pointer.

Detlef Bosau

Mitglied
Guten Tag.

Ich bin neu hier und mene Frage ist vielleicht eine Anfängerfrage, ich stelle sie trotzden.

Ich bin nicht gut mit nichtstatischen inneren Klassen vertraut. Und bin vor allem mit dem -Gebrauch des this Pointers noch nicht klargekommen.


Ich habe mal ein Beispiel angeängt. Mich iirritiert der Ausdruck "Aussen.this.name", nach allem, was ich in der Doku zu Java finde, sollte es ein Keyword outer geben, es müsste dann outer.this,name heißen, das führt aber auf eine Fehlermeldung.

Kann mir da bitte jemand aufs Fahrrad helfen?

Danke.

Detlef
 

Anhänge

  • Aussen.java
    1.001 Bytes · Aufrufe: 2

httpdigest

Top Contributor
Hier erstmal der Code formatiert und nicht als Datei sondern als Code-Block:
Java:
import java.lang.String;
import java.lang.Integer;

class Aussen {
  class inner {
    //String name;
    void ausgabe() {
      System.out.println("Name des äußeren Objekts: ");
      //Aussen.this.ausgabe();
      System.out.println(Aussen.this.name);
    }
  }

  String name;
  inner i;

  Aussen(String name) {
    this.name = name;
  }

  void ausgabe() {
    System.out.println("Name: " + name);
  }

  public static void main(String[] args) {
    System.out.println("Anzahl der Argumente:" + args.length);
    System.out.println("a: " + args[0] + " b: " + args[1]);

    int a, b, u, v, d;

    a = Integer.decode(args[0]);
    b = Integer.decode(args[1]);

    Aussen o1 = new Aussen("outer 1");
    Aussen o2 = new Aussen("outer 2");

    o1.ausgabe();
    o2.ausgabe();

    inner i1 = o1.new inner();
    inner i2 = o2.new inner();

    i1.ausgabe();
    i2.ausgabe();
  }
}
 

httpdigest

Top Contributor
"outer" ist kein Keyword in der Java-Syntax. Wo hast du das denn her?
X.this.y bedeutet: Wenn ich mich innerhalb einer nicht-statischen inneren Klasse befinde, die Instanz der äußeren Klasse X und davon das Feld/Member y.
 

Neumi5694

Top Contributor
So was wie "Aussen.this.name" ergibt nur dann Sinn, wenn "Innen" von "Aussen" ableitet
Die "Innen-Klasse" muss nicht zwingend ein "Aussen"-Objekt kennen, deshalb funktioniert Aussen.this auch nicht, wenn sie nicht ableitet.

Es gibt hier mal wieder ein kleines Problem mit den Begriffen. Eine Klasse kann nur statische Eigenschaften haben. Erst, wenn sie instanziert wird, gibt es nicht statische. Von Ableitungen mal abgesehen, greift man bei nicht statischen Felder stets auf die Eigenschaften eines anderen Objekts (bzw. die Instanz einer Klasse) zu, nicht auf die einer anderen Klasse.
Sobald man das verinnerlicht hat, lichtet sich der Nebel wie von selbst.
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Für äussere Klassen kommt wohl eher "super" in Frage: https://www.geeksforgeeks.org/super-keyword/
Äußere Klasse hat nichts mit "parent class" zu tun.

Die parent class ist die Klasse, von der eine Klasse abgeleitet wird.

Bei der äußeren Klasse ist der Name der Klasse korrekt. Das nennt sich in der Java Language Specification "qualified this" und wird hier behandelt (JLS 15.8.4):

15.8.4. Qualified this​

Any lexically enclosing instance (§8.1.3) can be referred to by explicitly qualifying the keyword this.

Let n be an integer such that TypeName denotes the n'th lexically enclosing class or interface declaration of the class or interface whose declaration immediately encloses the qualified this expression.

The value of a qualified this expression TypeName.this is the n'th lexically enclosing instance of this.

If TypeName denotes a generic class, with type parameters F1,...,Fn, the type of the qualified this expression is TypeName<F1,...,Fn>. Otherwise, the type of the qualified this expression is TypeName.

It is a compile-time error if a qualified this expression occurs in a static context (§8.1.3).

It is a compile-time error if the class or interface whose declaration immediately encloses a qualified this expression is not an inner class of TypeName or TypeName itself.
 

KonradN

Super-Moderator
Mitarbeiter
So was wie "Aussen.this" ergibt nur dann Sinn, wenn Innen von Aussen ableitet.
Was habt Ihr denn immer mit dem ableiten? Ableiten ist Inheritance! Inheritance ist doch etwas ganz anderes. Daher kein super. Und es muss eine nicht statische inner class sein, denn dann kennt die Instanz der inneren Klasse die Instanz der äußeren Klasse.

Das ist aber KEINE Inheritance! Wäre das eine Inheritance, dann könnte man this der inneren Klasse ja zu eine äußeren klasse casten. Das geht aber nicht. Denn es ist eben keine Abgeleitete Klasse sondern nur eine Innere Klasse!
 

Neumi5694

Top Contributor
Was habt Ihr denn immer mit dem ableiten? Ableiten ist Inheritance! Inheritance ist doch etwas ganz anderes. Daher kein super. Und es muss eine nicht statische inner class sein, denn dann kennt die Instanz der inneren Klasse die Instanz der äußeren Klasse.

Das ist aber KEINE Inheritance! Wäre das eine Inheritance, dann könnte man this der inneren Klasse ja zu eine äußeren klasse casten. Das geht aber nicht. Denn es ist eben keine Abgeleitete Klasse sondern nur eine Innere Klasse!
Sach ich doch. Nur dann kann das funktionieren.
 

KonradN

Super-Moderator
Mitarbeiter
So was wie "Aussen.this.name" ergibt nur dann Sinn, wenn "Innen" von "Aussen" ableitet
Die "Innen-Klasse" muss nicht zwingend ein "Aussen"-Objekt kennen, deshalb funktioniert Aussen.this auch nicht, wenn sie nicht ableitet.

Was bitte habe ich hier übersehen?

In dem zweiten Teil geht es dann ja auch nur um statische Dinge und Instanzen von Klassen:
Es gibt hier mal wieder ein kleines Problem mit den Begriffen. Eine Klasse kann nur statische Eigenschaften haben. Erst, wenn sie instanziert wird, gibt es nicht statische. Von Ableitungen mal abgesehen, greift man bei nicht statischen Felder stets auf die Eigenschaften eines anderen Objekts (bzw. die Instanz einer Klasse) zu, nicht auf die einer anderen Klasse.
Sobald man das verinnerlicht hat, lichtet sich der Nebel wie von selbst.


Gibt es evtl. Probleme mit dem Begriff "Ableiten"? Haben wir da unterschiedliche Definitionen?
Der Begriff Ableiten meint Inheritance - wenn man also z.B. danach sucht, dann findet man Dinge wie:

Ich will keine Wortklauberei veranstalten, aber diese Aussage in deinem ersten Abschnitt ist aus meiner Sicht einfach komplett falsch in diesem Zusammenhang. Aussen.this.name macht eben nur dann Sinn wenn:
  • man nicht in einem statischen Context ist ("It is a compile-time error if a qualified this expression occurs in a static context (§8.1.3).")
  • Wir in der Klasse Aussen oder einer (nicht statischen) inneren Klasse von Aussen sind. ("It is a compile-time error if the class or interface whose declaration immediately encloses a qualified this expression is not an inner class of TypeName or TypeName itself.")


Der Punkt könnte mir egal sein, aber hier geht es um den TE und andere Anfänger, die über diesen Thread stolpern. Und bei einer Frage zu Inneren Klassen dann mit super und ableiten anzufangen, das ist einfach schlicht falsch und das rücke ich gerade! Und ich denke, ich habe die JLS aufgezeigt. Wenn Du die Unterschiede zwischen inneren Klassen und abgeleiteten Klassen nachlesen willst: Ich habe nur auf 8.1 allgemein verwiesen - aber Du kannst beides nachlesen: 8.1.3 beschreibt "Inner Classes and Enclosing Instances" und 8.1.4 beschreibt "Superclasses and Subclasses".

Und der Begriff ableiten umschreibt nun einmal das eine "subclass" von einer "superclass" abgeleitet wird. Der Begriff umfasst nicht, dass eine "inner class" eine "enclosing instance" hat.

Ich denke, damit ist alles gesagt und der Sachverhalt deutlich geworden.
 

Detlef Bosau

Mitglied
"outer" ist kein Keyword in der Java-Syntax. Wo hast du das denn her?
X.this.y bedeutet: Wenn ich mich innerhalb einer nicht-statischen inneren Klasse befinde, die Instanz der äußeren Klasse X und davon das Feld/Member y.

ich finde jetzt die -Quelle nicht aber ich sehe ja, daß es nicht funktioniert, daher frage ich ja. (Und ich habe mir schoh eih paar Nächte zu dem Thea um die Ohren geschlagen. Und leider auch bei stackoverflow und den Dokus bei Oracle nichts wirklich übersichtliches gefunden,)

Daher frage ich ja.
 

KonradN

Super-Moderator
Mitarbeiter
Hast Du denn durch den Thread eine verständliche Antwort bekommen oder ist noch etwas offen?

Bezüglich Dokumentation: Die Java Language Specification ist - gerade am Anfang - ggf. schwer zu lesen, aber das ist natürlich bei allen Fragen zur Sprache Java sozusagen die "oberste Instanz".
 

httpdigest

Top Contributor
ich finde jetzt die -Quelle nicht aber ich sehe ja, daß es nicht funktioniert, daher frage ich ja. (Und ich habe mir schoh eih paar Nächte zu dem Thea um die Ohren geschlagen. Und leider auch bei stackoverflow und den Dokus bei Oracle nichts wirklich übersichtliches gefunden,)

Daher frage ich ja.
Und daher hab ich ja auch geantwortet. Also, "outer" ist kein Schlüsselwort in Java. Und in dem Muster X.this.y muss X eine äußere Klasse sein, die auch so heißt.
Wenn du eine Klasse hast, die zufälligerweise outer heißen würde, würde das natürlich gehen.
Die von dir in deinem ersten Post gezeigte äußere Klasse heißt aber nunmal nicht outer, sondern Aussen. Somit geht outer.this... nicht.
 

Detlef Bosau

Mitglied
So was wie "Aussen.this.name" ergibt nur dann Sinn, wenn "Innen" von "Aussen" ableitet
Die "Innen-Klasse" muss nicht zwingend ein "Aussen"-Objekt kennen, deshalb funktioniert Aussen.this auch nicht, wenn sie nicht ableitet.

Es gibt hier mal wieder ein kleines Problem mit den Begriffen. Eine Klasse kann nur statische Eigenschaften haben. Erst, wenn sie instanziert wird, gibt es nicht statische. Von Ableitungen mal abgesehen, greift man bei nicht statischen Felder stets auf die Eigenschaften eines anderen Objekts (bzw. die Instanz einer Klasse) zu, nicht auf die einer anderen Klasse.
Sobald man das verinnerlicht hat, lichtet sich der Nebel wie von selbst.
So was wie "Aussen.this.name" ergibt nur dann Sinn, wenn "Innen" von "Aussen" ableitet
Die "Innen-Klasse" muss nicht zwingend ein "Aussen"-Objekt kennen, deshalb funktioniert Aussen.this auch nicht, wenn sie nicht ableitet.

Es gibt hier mal wieder ein kleines Problem mit den Begriffen. Eine Klasse kann nur statische Eigenschaften haben. Erst, wenn sie instanziert wird, gibt es nicht statische. Von Ableitungen mal abgesehen, greift man bei nicht statischen Felder stets auf die Eigenschaften eines anderen Objekts (bzw. die Instanz einer Klasse) zu, nicht auf die einer anderen Klasse.
Sobald man das verinnerlicht hat, lichtet sich der Nebel wie von selbst.
Innen ist eine innere Klasse, NICHT abgeleitet und NICHT statisch. Jetzt lese ich mal die anderen Antworten durch, ich denke, dazu ist schon einiges gesagt worden.
 

Detlef Bosau

Mitglied
Hast Du denn durch den Thread eine verständliche Antwort bekommen oder ist noch etwas offen?

Bezüglich Dokumentation: Die Java Language Specification ist - gerade am Anfang - ggf. schwer zu lesen, aber das ist natürlich bei allen Fragen zur Sprache Java sozusagen die "oberste Instanz".
Ich bin noch dabei. Und ja, die doku ist sperrig - aber so ganz am Anfang stehe ich da auch nicht. Ich bin erst die Tage auf nicht statische innere Klassen gestossen - und was dazu im Netz steht ist ziemlich unübersichtlich. Und auch die Verwendung des Begriffes "static" ist gewöhnungsbedürftig.
 

Detlef Bosau

Mitglied
"outer" ist kein Keyword in der Java-Syntax. Wo hast du das denn her?
X.this.y bedeutet: Wenn ich mich innerhalb einer nicht-statischen inneren Klasse befinde, die Instanz der äußeren Klasse X und davon das Feld/Member y.
Ich fürchte, jetzt gehen Klasse und Objekt etwas durcheinander. Ich möchte in dem Beispiel nicht auf ein -Element der äußerejn Klasse zugreifen sondern auf ein Attribut (das ist eigentlich der bessere -begriff) des Obejkts o1 oder o2. Und das war auch mein eigentoicer Gedanke, i1 und i2 sind Elemente (ich habe für nicht statiscze Innere Klassen den Begriff "Elementklassen" gelesen) der Objekte o1 und o2. Und eigentlicz wolte ich einen Zeiger auf das "Eigentümerobjekt" (wie heisst das richtig?)
 

KonradN

Super-Moderator
Mitarbeiter
Also die letzte Aussage habe ich noch nicht ganz verstanden. Aber das kann an mir liegen, denn die Deutschen Begriffe sind mir nicht ganz so geläufig. (Ich bleibe lieber bei den englischen Begriffen um eben keine Verwechslung zu haben. Die englischen Begriffe sind in der Java Language Specification klar und sauber benutzt, so dass die Bedeutung klar ist bzw. darüber geklärt werden kann.)

Eine nicht statische innere Klasse hat Zugriff auf die Elemente der Äußeren Klasse. Daher kannst Du eine Instanz einer inneren Klasse nur erstellen, wenn Du in einem Context bist, bei dem Du ein eine Äüßere Klasse hast. Also bei Deinem Code hast Du das in der Methode main nicht - daher dieser Konstrukt mit o1.new bzw. o2.new.

Das findet sich übrigens in der JLS in 15.9.2 - Determing Enclosing Instances:
(15.9 behandelt die Erzeugung neuer Instanzen)

Die Instanz der äußeren Klasse ist daher "enclosing instance" - die Äußere Instanz.
Und in den erzeugten inneren Instanzen kannst Du auf die enclosing instance zugreifen, d.h. auf alle member (das was Du als Elemente bezeichnet hast) - und das sind dann halt einmal die Instanz o1 und einmal die Instanz o2.

Ich bin mir jetzt aber nicht ganz sicher, ob Du Dir hier nich evtl. zu viele Gedanken machst. Diese inneren Klassen kommen in der Praxis nicht ganz so oft vor. Die inneren Klassen, die ich so kenne, sind in erster Linie static (Also so wie bei Map.Entry). Ich sehe da vor allem Probleme in Bezug auf Clean Code. Es macht evtl. Sinn, so Dinge zu kennen (Wobei ich die Möglichkeit, eine innere Klasse in einer Methode zu erstellen, bis vor kurzem komplett ausgeblendet hatte. Wozu das gut sein könnte sehe ich bisher nicht.) Hintergrund ist, dass Du eine Komplexität in ein Stück Code quetscht, das Du nicht unit testen kannst. Bei allen Ansätzen der Entwicklung, die ich so kenne und für gut befunden habe, ist das immer etwas, das direkt nach einem Refactoring schreit!

Es ist super, dass Du hier so genau hin schaust und so gut überlegst. Das ist echt super und ich denke, die JLS (die ich immer gerne als Referenz in so Fragen verlinke) kann für Dich sehr interessant sein. Zumindest wäre das gerade mein Bauchgefühl. Aber natürlich kannst Du gerne weiter fragen - und ich werde dann weiter versuchen, da verständliche Antworten zu schreiben. (Und wenn die JLS eher noch zu schwer zu verstehen ist, dann sind die Links ggf einfach zu ignorieren!)
 

gandaf

Mitglied
Moin,

das, was dich vielleicht verwirrt, ist, dass das Feld der äußeren Klasse auch nur mit foo angesprochen werden kann, anstatt mit Outer.this.foo - solange das "shadowing" dies nicht verhindert... Alles Weitere kannst du dazu hier nachlesen:

 

Detlef Bosau

Mitglied
Also die letzte Aussage habe ich noch nicht ganz verstanden. Aber das kann an mir liegen, denn die Deutschen Begriffe sind mir nicht ganz so geläufig. (Ich bleibe lieber bei den englischen Begriffen um eben keine Verwechslung zu haben. Die englischen Begriffe sind in der Java Language Specification klar und sauber benutzt, so dass die Bedeutung klar ist bzw. darüber geklärt werden kann.)

Eine nicht statische innere Klasse hat Zugriff auf die Elemente der Äußeren Klasse. Daher kannst Du eine Instanz einer inneren Klasse nur erstellen, wenn Du in einem Context bist, bei dem Du ein eine Äüßere Klasse hast. Also bei Deinem Code hast Du das in der Methode main nicht - daher dieser Konstrukt mit o1.new bzw. o2.new.

Das findet sich übrigens in der JLS in 15.9.2 - Determing Enclosing Instances:
(15.9 behandelt die Erzeugung neuer Instanzen)

Die Instanz der äußeren Klasse ist daher "enclosing instance" - die Äußere Instanz.
Und in den erzeugten inneren Instanzen kannst Du auf die enclosing instance zugreifen, d.h. auf alle member (das was Du als Elemente bezeichnet hast) - und das sind dann halt einmal die Instanz o1 und einmal die Instanz o2.

Ich bin mir jetzt aber nicht ganz sicher, ob Du Dir hier nich evtl. zu viele Gedanken machst. Diese inneren Klassen kommen in der Praxis nicht ganz so oft vor. Die inneren Klassen, die ich so kenne, sind in erster Linie static (Also so wie bei Map.Entry). Ich sehe da vor allem Probleme in Bezug auf Clean Code. Es macht evtl. Sinn, so Dinge zu kennen (Wobei ich die Möglichkeit, eine innere Klasse in einer Methode zu erstellen, bis vor kurzem komplett ausgeblendet hatte. Wozu das gut sein könnte sehe ich bisher nicht.) Hintergrund ist, dass Du eine Komplexität in ein Stück Code quetscht, das Du nicht unit testen kannst. Bei allen Ansätzen der Entwicklung, die ich so kenne und für gut befunden habe, ist das immer etwas, das direkt nach einem Refactoring schreit!

Es ist super, dass Du hier so genau hin schaust und so gut überlegst. Das ist echt super und ich denke, die JLS (die ich immer gerne als Referenz in so Fragen verlinke) kann für Dich sehr interessant sein. Zumindest wäre das gerade mein Bauchgefühl. Aber natürlich kannst Du gerne weiter fragen - und ich werde dann weiter versuchen, da verständliche Antworten zu schreiben. (Und wenn die JLS eher noch zu schwer zu verstehen ist, dann sind die Links ggf einfach zu ignorieren!)
Es ist generell hilfreich, wenn du die begriffe in D und E schreibst, zumal die englischen Begriffe die "originalen" sind. "enclosing instance" - du hast vorhin in meiner off list nachricht gelesen, wie sehr ich da eiere, "enclosing instance" ist extrem griffig und präzise.
 

KonradN

Super-Moderator
Mitarbeiter
Tobias: es steht Dir frei, mich zu korrigieren. Ich habe mich auch immer auf die JLS bezogen und diese verlinkt. Wo habe ich etwas missverstanden?
 

Detlef Bosau

Mitglied
Moin,

das, was dich vielleicht verwirrt, ist, dass das Feld der äußeren Klasse auch nur mit foo angesprochen werden kann, anstatt mit Outer.this.foo - solange das "shadowing" dies nicht verhindert... Alles Weitere kannst du dazu hier nachlesen:

Danke für den Link, da bin ich wohl auch auf das Outer gestoßen (ich hatte hinterher outer und Outer ausprobiert), man fragte danach. Es hat nicht funktioniert. Ich werde mich also nochmal über die JLS hermachen müssen, wie man member variables der enclosing instance adressiert. Ich weiß nicht, ob ich das jemals brauchen werde. Aber ich sehe, daß ich in Java wesentliche Verständnislücken habe und manches falsch verstanden habe. Und das ist nicht akzeptabel. Und wenn ich den link oben sehe: es geht nicht um die "outer class". Es geht um die Enclosing Instance. Irgendwie gehen hier die Begriffe Instanz und Klasse etwas durcheinander. Und bei meinem Codebeispiel wird deutlich, daß ich auf die unterschiedlichen Instanzen raus wollte.
 

httpdigest

Top Contributor
Ich fürchte, jetzt gehen Klasse und Objekt etwas durcheinander. Ich möchte in dem Beispiel nicht auf ein -Element der äußerejn Klasse zugreifen sondern auf ein Attribut (das ist eigentlich der bessere -begriff) des Obejkts o1 oder o2. Und das war auch mein eigentoicer Gedanke, i1 und i2 sind Elemente (ich habe für nicht statiscze Innere Klassen den Begriff "Elementklassen" gelesen) der Objekte o1 und o2. Und eigentlicz wolte ich einen Zeiger auf das "Eigentümerobjekt" (wie heisst das richtig?)
Nein, Klasse und Objekt wurden niemals hier verwechselt. Du hast es nur angenommen.
Ich schrieb "Instanz der äußeren Klasse". Also " ----> INSTANZ <---- der äußeren Klasse". Eine Instanz einer Klasse ist ein Objekt dieser Klasse.

Genausowenig haben Leute "danach gefragt", dass du "Outer" oder "outer" ausprobierst. Es wurde dir bereits mindestens zehnmal gesagt, wie man auf Instanzvariablen der äußeren Klasse zugreift (sprich: auf Variablen eines OBJEKTES der äußeren Klasse).

es geht nicht um die "outer class". Es geht um die Enclosing Instance. Irgendwie gehen hier die Begriffe Instanz und Klasse etwas durcheinander. Und bei meinem Codebeispiel wird deutlich, daß ich auf die unterschiedlichen Instanzen raus wollte.
Das haben von Anfang an alle verstanden. Und nein, hier gehen keine Begriffe durcheinander. Instanz einer Klasse ist ein Objekt der Klasse. Niemand hat gesagt, dass du direkt die Klasse meinst.
 

Detlef Bosau

Mitglied
Nein, Klasse und Objekt wurden niemals hier verwechselt. Du hast es nur angenommen.
Ich schrieb "Instanz der äußeren Klasse". Also " ----> INSTANZ <---- der äußeren Klasse". Eine Instanz einer Klasse ist ein Objekt dieser Klasse.

Genausowenig haben Leute "danach gefragt", dass du "Outer" oder "outer" ausprobierst. Es wurde dir bereits mindestens zehnmal gesagt, wie man auf Instanzvariablen der äußeren Klasse zugreift (sprich: auf Variablen eines OBJEKTES der äußeren Klasse).


Das haben von Anfang an alle verstanden.
Ich mag nicht darüber reden, was "alle" verstanden haben, ich kann und darf nicht für "alle" sprechen.
Aber ich spreche für mich, wenn ich sage, daß ich dir nichts getan habe. Und daß mich dein Ton etwas irritiert.
 

KonradN

Super-Moderator
Mitarbeiter
da bin ich wohl auch auf das Outer gestoßen
Das Outer als Name für die äußere Klasse und Inner als Name für die innere Klasse ist generell im englischen Sprachraum verbreitet. Das findet sich z.B. auch in den Beispielen der JLS.

Die Zugriffe sind generell recht einfach zu verstehen. Einfach einmal ein kleines Beispiel:
Java:
public class Outer {
    private String outerOnly = "outer";
    private String innerAndOuter = "outer";
    private static String innerAndOuterStatic = "outer";
    private static String outerStaticInnerNot = "outer static";
    class Inner {
        private String innerAndOuter = "inner";
        private static String innerAndOuterStatic = "inner";

        private String outerStaticInnerNot = "inner non static";

        public void printValues() {
            System.out.println("Outer.this.outerOnly = " + Outer.this.outerOnly);
            System.out.println("outerOnly = " + outerOnly);

            System.out.println("innerAndOuter = " + innerAndOuter);
            System.out.println("this.innerAndOuter = " + this.innerAndOuter);
            System.out.println("Outer.this.innerAndOuter = " + Outer.this.innerAndOuter);

            System.out.println("innerAndOuterStatic = " + innerAndOuterStatic);
            System.out.println("Inner.innerAndOuterStatic = " + Inner.innerAndOuterStatic);
            System.out.println("Inner.this.innerAndOuterStatic = " + Inner.this.innerAndOuterStatic);
            System.out.println("Outer.innerAndOuterStatic = " + Outer.innerAndOuterStatic);
            System.out.println("Outer.this.innerAndOuterStatic = " + Outer.this.innerAndOuterStatic);

            System.out.println("outerStaticInnerNot = " + outerStaticInnerNot);
            System.out.println("this.outerStaticInnerNot = " + this.outerStaticInnerNot);
            System.out.println("Outer.outerStaticInnerNot = " + Outer.outerStaticInnerNot);
        }

        public void testParameter(String innerAndOuter) {
            System.out.println("innerAndOuter = " + innerAndOuter);
        }

        public void testLocalVariable() {
            String innerAndOuter = "local variable";
            System.out.println("innerAndOuter = " + innerAndOuter);
        }
    }

    public static void main(String[] args) {
        Outer o = new Outer();
        Inner i = o.new Inner();
        i.printValues();
        i.testParameter("parameter");
        i.testLocalVariable();
    }
}

Hier kann man sehr schön erkennen, wie man schon vorhandene Variablen verstecken kann. Aber man kann die Variablen auch immer direkt angeben.

Das geht auch mit statischen Variablen. Dabei noch die Anmerkung: Java lässt den Zugriff aus statische Variablen über eine Instanz zu. Das ist aber eine schlechte Praxis und wird z.B. von IntelliJ auch mit Warnungen versehen.

Wenn man etwas nich qualifiziert angibt, dann hat man halt in etwa diese Ebenen:
1. Lokale Variable und Paramter - wenn ein Bezeichner hier schon gefunden wird, dann wird er genommen.
2. eigene Instanz / Klasse
3. umgebene Instanz / Klasse

Wichtig sind hier ggf. noch ein ein paar Dinge, die interessant sein könnten:

a) Diese inneren Klassen können beliebig verschachtelt werden. Die innere Klasse kann eine innere Klasse haben, die eine innere Klasse hat ...
b) Die JLS unterscheidet: Inner Class vs. Nested Class. Eine inner class ist nicht static, eine nested class kann static haben. (Eine inner class ist also auch eine nested class (8.1.3 "An inner class is a nested class that is not explicitly or implicitly static.")
 

KonradN

Super-Moderator
Mitarbeiter
Bezüglich der sinnvollen Nutzung wollte ich noch ein paar Worte schreiben. Das ist aber natürlich rein meine Sicht. Es gibt ganz klar andere Sichten - was auch am Ende deutlich wird.

Wenn man sich so innere Klassen anschaut, dann sieht es erst einmal positiv aus: Man kann einen komplizierten Sachverhalt in einer Klasse, ja sogar in einer Methode weiter untergliedern. Das sieht doch auf den ersten Blick positiv aus: Statt einer langen Methode oder einer sehr großen Klasse mit einer flachen Struktur bekomme ich eine weitere Untergliederung in Form von Klassen von denen ich dann Instanzen nutzen kann.
Das sieht also erst einmal wie eine Chance aus, Code sauber zu unterteilen.

Aber die Probleme werden dennoch recht schnell sichtbar, denn wir haben ja gewisse Anforderungen an unseren Code.

  • Man möchte eine möglichst gute Wiederverwendung haben. Das wird aber durchaus zu einem Problem. Bei inneren Klassen (inner class) habe ich die feste Zuordnung zu einer Instanz der äußeren Klasse. Ok, man könnte statt dessen eine nested class haben, da hätte man die Zugehörigkeit nicht.
  • Man möchte ja versuchen, Klassen klein und übersichtlich zu halten. Single responsibility principle von SOLID wäre hier ein Stichwort. Das sehe ich hier zumindest als problematisch an.
  • Macht es einen Unterschied, ob ich eine nested class über eine Klasse anspreche oder statt dessen über einen Namespace? Ob ich nun "org.example.MyClass.MyNestedClass" anspreche oder org.example.internals.MyNoLongerNestedClass oder so - macht nicht wirklich einen Unterschied. Ich sehe keinen Grund für die innere Klasse.
  • Es kann Sinn machen als Kapselung, wenn man das wirklich nicht braucht. Beispiel wäre z.B. eine Datenstruktur, die interne Nodes hat. Eine List oder ein Tree oder so. Aber dann sollte es nicht nach außen gehen.
  • Unit Tests - die inneren Klassen erschweren Unit Tests (meiner Meinung nach). Das ist mit ein Grund, wieso ich die z.B. nicht verwenden würde, wenn da Logik mit einfliesst.

Wenn man sich das alles etwas anschaut, dann finden wir regelmäßig Klassen in Interfaces oder Klassen innerhalb des Java Frameworks. Und da kann man einmal drauf schauen um da vielleicht zu veranschaulichen, wasich als problematisch ansehe oder nicht:

Map.Entry ist eine solche Klasse (Ok, Interface, nicht Klasse). Es wird halt einfach ein Key/Value paar gespeichert, was halt Maps benötigen. Das ist aber aus meiner Sicht etwas, das von vielen Klassen benutzt wird und das auch nach außen gegeben wird. Also nicht etwas, das als innere Angelegenheit der Klasse dient. Ich hätte es daher zu java.util.MapEntry statt java.util.Map.Entry gemacht. (Zumal es ja auch default Methoden enthält und so...)

Arrays.ArrayList. Hier gibt es eine weitere Klasse ArrayList - innerhalb der Klasse Arrays. Hier wurde also eine ganze List Implementation in einer Utility Klasse gebaut. Das ist in meinen Augen tatsächlich eher ein Unding. Und ich kann es nicht einmal verlinken - die Arrays.ArrayList hat nicht einmal eine Dokumentation. Was also die Methode asList zurück gibt und wie sich dies verhält: Who cares? Als Entwickler will man ja nicht wissen, was man da wirklich zurück bekommt. (Es gibt nur ein paar Hinweise in der Beschreibung der Methode asList). Und die Liste ist ja auch modifizierbar - warum also nicht java.util.ArrayList nutzen statt java.util.Arrays.ArrayList? (Wir haben hier eine öffentliche API, bekommen ein Objekt einer Klasse zurück und zu dieser Klasse erwarte ich eine Dokumentation. Und die fehlt hier. In eigenen Projekten mag man auf JavaDoc verzichten und so, aber doch bitte nicht bei so APIs. Zumal Java das Framework sonst sehr gut dokumentiert hat!)

Man erkennt also deutlich meine ablehnende Sicht und auch, dass andere Entwickler (z.B. die vom Java Framework) es schlicht anders sehen. Aber ich denke, dass die Gründe, die durch diverse Clean Code Grundsätze vorgesehen sind. Das sind keine absoluten Werte, so dass es zu einer Abwägung kommen muss - und die kann durchaus unterschiedlich ausfallen.
 

mihe7

Top Contributor
Macht es einen Unterschied, ob ich eine nested class über eine Klasse anspreche oder statt dessen über einen Namespace? Ob ich nun "org.example.MyClass.MyNestedClass" anspreche oder org.example.internals.MyNoLongerNestedClass oder so
Ja, wobei das eine Frage des gewählten Bezeichners ist. Kommt es zu Namenskonflikten, dann muss ich für wenigstens eine der beiden Klassen den vollqualifizerenden Namen angeben; das ist nicht nur lästig sondern stört beim Lesen. Bei einer static nested class kann ich dagegen die umschließende Klasse importieren und erhalte über diese den Zugriff.

Heißt: mit einer enclosing class habe ich einen importierbaren Namespace.

javax.persistence.criteria.Order ist super, wenn Du Aufträge verwaltest -> com.mycompany.myproduct.orders.entity.Order. Noch lustiger, wenn Du dann eine weitere "SortOrder" auf fachlicher Seite haben willst und dann auf der UI-Seite dann ein Framework hängst, das auch eine SortOrder kennt, wie z. B. Primefaces. Dann übersetzt Du org.primefaces.model.SortOrder in Deine com.mycompany.common.SortOrder, die letztlich auf eine javax.persistence.Order abgebildet wird, um eine Liste von com.mycompany.myproduct.order.entity.Order in einer bestimmten Reihenfolge zu erhalten :)
 

KonradN

Super-Moderator
Mitarbeiter
Ja, wobei das eine Frage des gewählten Bezeichners ist. Kommt es zu Namenskonflikten, dann muss ich für wenigstens eine der beiden Klassen den vollqualifizerenden Namen angeben; das ist nicht nur lästig sondern stört beim Lesen. Bei einer static nested class kann ich dagegen die umschließende Klasse importieren und erhalte über diese den Zugriff.

Ja, das kann als Grund angesehen werden. Ich selbst bewerte dieses Problem aber nicht als schwerwiegend.
Und die Lösung für so ein Problem wäre eigentlich ein Aliasing Mechanismus beim Import, also etwas wie:
import javax.persistence.criteria.Order as PersistenceOrder;

Nur eben scheinen das viele nicht als Problem anzusehen, denn dieses Aliases Thema ist ja so alt wie Java selbst, oder nicht?

Und nested classes sind da auch nicht wirklich als Idee führend, sonst wäre ja viel mehr eine nested Class?

Danke für das Argument - mir war diese Thematik nicht eingefallen. Und die Bewertung war nicht als "Was soll der Quatsch?" gemeint sondern einfach nur ein kurzer Versuch es zu integrieren / abzuwägen im Sinne von meiner letzten Aussage des anderen Posts: "Das sind keine absoluten Werte, so dass es zu einer Abwägung kommen muss - und die kann durchaus unterschiedlich ausfallen."
 

mihe7

Top Contributor
Ich selbst bewerte dieses Problem aber nicht als schwerwiegend.
Ne, schwerwiegend ist das nicht, das betrifft auch nur wenige Fälle. Man könnte ja hergehen und die eigenen Klassen umbenennen, aber da überwiegt dann m. E. der Nachteil. Was anderes wäre es, wenn es an jeder Stelle im Code zu Konflikten käme, dann würde ich mir über andere Namen ernsthaft Gedanken machen.

Und ja, das Aliasing wäre die Lösung schlechthin. Hatte ich gar nicht mitbekommen, dass das in Java schon ein ewiges Thema war bzw. ist.

Und nested classes sind da auch nicht wirklich als Idee führend
Wenn ich an bestimmte enums denke, finde ich die Idee gar nicht schlecht. Player.Type, Field.Type, was weiß ich. Kann man natürlich auch top-level PlayerType und FieldType draus machen. Da müsste ich jetzt in mich gehen, warum ich das so empfinde :)

Und die Bewertung war nicht als "Was soll der Quatsch?" gemeint
Hätte ich jetzt auch nicht so verstanden. Es ging nur um den Unterschied zwischen top-level class und nested class.
 

KonradN

Super-Moderator
Mitarbeiter
Wenn ich an bestimmte enums denke, finde ich die Idee gar nicht schlecht. Player.Type, Field.Type, was weiß ich. Kann man natürlich auch top-level PlayerType und FieldType draus machen. Da müsste ich jetzt in mich gehen, warum ich das so empfinde :)
Da bin ich sogar bei Dir. Da ist dann ja in der Regel auch keine Logik drin, die Unit Tests benötigt. Das sind dann so Dinge, die auch automatisch static sind. Records wohl auch - da wird also auch gesehen, dass dies eine gute Idee sein dürfte für nested classes. (Man braucht halt doch teilweise interne Datenstrukturen zur Datenhaltung - halt der typische Node in List oder Tree Klassen.)

Hätte ich jetzt auch nicht so verstanden. Es ging nur um den Unterschied zwischen top-level class und nested class.
Das sind die Auswirkungen eines gewissen Users ... Ich vertrete meine Position ja sehr aktiv und mindestens eine Person hat den Eindruck gewonnen, dass ich der Herr über die ganze Welt bin und alles bestimmen will. Dass Du das nicht so siehst, ist mir klar. Denn wir haben ja - nach meinem Gefühl - immer eine durchaus gute, sachliche Kommunikation mit Austausch von Argumenten und damit hast Du mir ja schon sehr oft zumindest zu denken zu geben und oft genug mich auch umgestimmt.

Aber da ja auch Andere den Thread lesen war es mir wichtig, das noch etwas zu betonen - denn ich sehe mich durchaus nicht als Mittelpunkt DER Welt, aber ich bin nun einmal der Mittelpunkt MEINER Welt und kann nur auf Basis meiner bisherigen Erkenntnisse und Erfahrungen eben genau mein Weltbild vertreten. :)
 

Detlef Bosau

Mitglied
Das Outer als Name für die äußere Klasse und Inner als Name für die innere Klasse ist generell im englischen Sprachraum verbreitet. Das findet sich z.B. auch in den Beispielen der JLS.

Die Zugriffe sind generell recht einfach zu verstehen. Einfach einmal ein kleines Beispiel:
Java:
public class Outer {
    private String outerOnly = "outer";
    private String innerAndOuter = "outer";
    private static String innerAndOuterStatic = "outer";
    private static String outerStaticInnerNot = "outer static";
    class Inner {
        private String innerAndOuter = "inner";
        private static String innerAndOuterStatic = "inner";

        private String outerStaticInnerNot = "inner non static";

        public void printValues() {
            System.out.println("Outer.this.outerOnly = " + Outer.this.outerOnly);
            System.out.println("outerOnly = " + outerOnly);

            System.out.println("innerAndOuter = " + innerAndOuter);
            System.out.println("this.innerAndOuter = " + this.innerAndOuter);
            System.out.println("Outer.this.innerAndOuter = " + Outer.this.innerAndOuter);

            System.out.println("innerAndOuterStatic = " + innerAndOuterStatic);
            System.out.println("Inner.innerAndOuterStatic = " + Inner.innerAndOuterStatic);
            System.out.println("Inner.this.innerAndOuterStatic = " + Inner.this.innerAndOuterStatic);
            System.out.println("Outer.innerAndOuterStatic = " + Outer.innerAndOuterStatic);
            System.out.println("Outer.this.innerAndOuterStatic = " + Outer.this.innerAndOuterStatic);

            System.out.println("outerStaticInnerNot = " + outerStaticInnerNot);
            System.out.println("this.outerStaticInnerNot = " + this.outerStaticInnerNot);
            System.out.println("Outer.outerStaticInnerNot = " + Outer.outerStaticInnerNot);
        }

        public void testParameter(String innerAndOuter) {
            System.out.println("innerAndOuter = " + innerAndOuter);
        }

        public void testLocalVariable() {
            String innerAndOuter = "local variable";
            System.out.println("innerAndOuter = " + innerAndOuter);
        }
    }

    public static void main(String[] args) {
        Outer o = new Outer();
        Inner i = o.new Inner();
        i.printValues();
        i.testParameter("parameter");
        i.testLocalVariable();
    }
}

Hier kann man sehr schön erkennen, wie man schon vorhandene Variablen verstecken kann. Aber man kann die Variablen auch immer direkt angeben.

Das geht auch mit statischen Variablen. Dabei noch die Anmerkung: Java lässt den Zugriff aus statische Variablen über eine Instanz zu. Das ist aber eine schlechte Praxis und wird z.B. von IntelliJ auch mit Warnungen versehen.

Wenn man etwas nich qualifiziert angibt, dann hat man halt in etwa diese Ebenen:
1. Lokale Variable und Paramter - wenn ein Bezeichner hier schon gefunden wird, dann wird er genommen.
2. eigene Instanz / Klasse
3. umgebene Instanz / Klasse

Wichtig sind hier ggf. noch ein ein paar Dinge, die interessant sein könnten:

a) Diese inneren Klassen können beliebig verschachtelt werden. Die innere Klasse kann eine innere Klasse haben, die eine innere Klasse hat ...
b) Die JLS unterscheidet: Inner Class vs. Nested Class. Eine inner class ist nicht static, eine nested class kann static haben. (Eine inner class ist also auch eine nested class (8.1.3 "An inner class is a nested class that is not explicitly or implicitly static.")
Ich habe in meinem Beispiel extra "Aussen" verwendet, um nicht über "Outer" zu stolpern. Vorhin habe ich mal etwas in die JLS geschaut, was mich etwas anstrengt, ich brauche (von Hartz IV ist das alles etwas mühsam) eine neue Brille, da bitte ich um Nachsicht für das langsame Tempo, Dieses "Outer.this...." ist mir noch nicht klar. Reden wir da über ein "qualified this"? Bei SO stoße ich gerade hierauf: SO zu qualified this
 

schlaui

Mitglied
this ist ein Schlüsselwort in Java, Outer oder Aussen hingegen nicht. Schlüsselwörter nehmen eine besondere Rolle ein.

Allgemein würde ich sagen, die JLS bringt dich pragmatisch/zielorientiert nicht weiter... Diese ist eher für eine andere Zielgruppe gedacht.
 

Detlef Bosau

Mitglied
this ist ein Schlüsselwort in Java, Outer oder Aussen hingegen nicht. Schlüsselwörter nehmen eine besondere Rolle ein.

Allgemein würde ich sagen, die JLS bringt dich pragmatisch/zielorientiert nicht weiter... Diese ist eher für eine andere Zielgruppe gedacht.
Die JLS ist aber die maßgebliche Referenz und ich muß dazu in der Lage sein, die Frage anhand der JLS zu klären, da gibt es keine zwei Meinungen. Wenn du Punkte in Flensburg kassierst, kannst du dich auch nicht rausreden, die StVO sei nicht für dich sondern für eine andere Zielgruppe geschrieben. Für mich gilt dasselbe.

Wenn ich hier also etwas auf dem Schlauch stehe, liegt das Problem bei mir und nicht bei der JLS.
 

M.L.

Top Contributor
Die JLS (wie die StVO) gibt Erläuterungen vor, warum Schlüsselwort x je nach Kontext (nicht mehr) sinnvoll ist (analog StVO: es gibt Regeln, die vom Fahrzeugtyp, Gewicht, Mindestgeschwindigkeit,... abhängen, also nicht für die alle Fahrer*innen interessant sind). Pädagogisch könnten die Openbooks weiterhelfen: Openbook Java und (später) Openbook Java SE 8
 

Detlef Bosau

Mitglied
Die JLS (wie die StVO) gibt Erläuterungen vor, warum Schlüsselwort x je nach Kontext (nicht mehr) sinnvoll ist (analog StVO: es gibt Regeln, die vom Fahrzeugtyp, Gewicht, Mindestgeschwindigkeit,... abhängen, also nicht für die alle Fahrer*innen interessant sind). Pädagogisch könnten die Openbooks weiterhelfen: Openbook Java und (später) Openbook Java SE 8
Das sehe ich nicht ganz so. Die Trennung zwischen Norm und Lehrbuch, die da durchklingt, mag klassisch sein. Ist aber spätestens seit Pascal - also dem "informellen Report" obsolet. Also seit über 50 Jahren. Natürliich ist Sekundärliteratur hilfreich. Aber an der JLS führt für jemanden, der sich ernsthaft mit Java befasst, kein Weg vorbei. Auch wenn man vielleicht nur selten reinschaut.
 

KonradN

Super-Moderator
Mitarbeiter
Aber an der JLS führt für jemanden, der sich ernsthaft mit Java befasst, kein Weg vorbei.
Da bin ich mir nicht so sicher. Sie ist auf jeden Fall das Fundament der Sprache Java und damit sowas wie eine oberste Instanz.

Aber wenn es ums Lernen geht, dann sind andere Quellen oft besser. Ich hatte nur eben den Eindruck gewonnen, dass Du da auch gerne sowas wie die "ultimative Antwort" haben wolltest, also nicht nur ein: "Schau mal, das und das funktioniert". Pädagogisch besser sind natürlich Texte, die explizit fürs Lernen geschrieben wurden. Aber da sind immer gewisse Gefahren:
  • die Quellen veralten (Bei Java nutzt man die Spezifikation der Version, die einen interessiert und gut ist es. Die ist aktualisiert und gültig!)
  • aus pädagogischer Sicht wird oft nur ein Teilbereich beleuchtet

Aber jemand, der sich ernsthaft mit Java befasst, der will ggf. nicht zwangsweise das komplette Java im Detail erfassen sondern dem reichen evtl. gewisse Teilbereiche. Ich denke, dass es nicht wenig Entwickler gibt, die mit Java ihr Geld verdienen, und die nie wirklich in die JLS geschaut haben.

Ich hatte aber den Eindruck gewonnen, dass dieser mehr theoretische Ansatz für Dich interessant ist - und Deine Sichtweise bestätigt diesen Eindruck.
 

httpdigest

Top Contributor
Es kommt darauf an, was man mit "sich ernsthaft mit Java zu beschäftigen" meint, bzw. wie man das definiert.

Die JLS brauchst du meiner Meinung nach, wenn du z.B. selber einen Compiler für die Sprache bauen möchtest, weil du dich dann "ernsthaft" mit der Sprache und den normativen Syntax-Definitionen beschäftigen musst. Ansonsten nicht.

Ich würde sagen, in der alltäglichen Nutzung von Java hat man ja eh nur ganz konkrete anwendungsspezifische Probleme und "fuchst" sich anhand von vielen vielen Beispielen (und mittlerweile mit der Hilfe von GitHub Copilot und ChatGPT) zu funktionierenden Lösungen durch.
Der Spruch "Probieren geht über Studieren" kommt nicht von ungefähr.
Desweiteren sind für konkrete Probleme eher einschlägige Seiten wie Stackoverflow oder baeldung.com mehr "approachable".
Die Sprache bzw. didaktische Aufarbeitung der JLS ist fürs Lernen absolut nicht geeignet. Es ist ein Referenzwerk, welches man zitieren kann, um schlau zu wirken, wenn Leute konkrete (Definitions-)Fragen haben. ;)
Es ist aber nicht geeignet, um eine Sprache zu lernen. Denn hier muss man mit vielen vielen vielen Beispielen und durch Übung herangeführt werden. Das Lesen von normativen Definitionen wie die in der JLS bleiben da einfach nicht hängen und nach 5 Minuten Lesen schläft man ein und hat nichts behalten, weil Menschen so nicht lernen.
Hier ist aber dann wieder die eingangs gestellte Definitionsfrage: Meinen wir mit "sich ernsthaft mit Java zu beschäftigen" immer noch, Java zu "lernen", oder meinen wir damit etwas anderes?

Ich verstehe aber mittlerweile den Sinn dieses Threads nicht mehr. Es geht hier ja längst nicht mehr um das initial beschriebene Problem, wie man auf die äußere Instanz eines Objektes einer inneren Klasse zugreift, sondern mehr darum, die persönliche Agenda bezüglich "wie beschäftigt man sich mit der Sprache Java?" zu vertreten.
 

Detlef Bosau

Mitglied
Da bin ich mir nicht so sicher. Sie ist auf jeden Fall das Fundament der Sprache Java und damit sowas wie eine oberste Instanz.

Aber wenn es ums Lernen geht, dann sind andere Quellen oft besser. Ich hatte nur eben den Eindruck gewonnen, dass Du da auch gerne sowas wie die "ultimative Antwort" haben wolltest, also nicht nur ein: "Schau mal, das und das funktioniert". Pädagogisch besser sind natürlich Texte, die explizit fürs Lernen geschrieben wurden. Aber da sind immer gewisse Gefahren:
  • die Quellen veralten (Bei Java nutzt man die Spezifikation der Version, die einen interessiert und gut ist es. Die ist aktualisiert und gültig!)
  • aus pädagogischer Sicht wird oft nur ein Teilbereich beleuchtet

Aber jemand, der sich ernsthaft mit Java befasst, der will ggf. nicht zwangsweise das komplette Java im Detail erfassen sondern dem reichen evtl. gewisse Teilbereiche. Ich denke, dass es nicht wenig Entwickler gibt, die mit Java ihr Geld verdienen, und die nie wirklich in die JLS geschaut haben.

Ich hatte aber den Eindruck gewonnen, dass dieser mehr theoretische Ansatz für Dich interessant ist - und Deine Sichtweise bestätigt diesen Eindruck.
Beides.

a) bin ich selber Dipl.-Inform., b) möchte ich beim Programmieren wissen was ich tue.

Zum Sinn des Threads: deswegen fragte ich nach dem qualified this, und ja, icz zabe da ein tutorial gefunden, da ist mir die syntax noch nicht klar, zumal man innere Klassen aucn noch "stapeln" kann, also wäre die Frage wie man etwa "stufen nach außen" diie Enclosing Instance hochläuft? (Und ja, das fürchterliche bei mir ist, daß ich da im Kopf immer nen Compiler baue und mich frage: was macht der daraus jetzt?
 

httpdigest

Top Contributor
zumal man innere Klassen aucn noch "stapeln" kann, also wäre die Frage wie man etwa "stufen nach außen" die Enclosing Instance hochläuft?
Da man eine Klasse mit demselben Namen nicht in sich selbst verschachtelt als innere Klasse definieren kann, also sowas geht nicht:
Java:
public class A {
  class A {}
}
ist es durch das "qualified this" dann auch wieder eindeutig, welche konkrete äußere Instanz gemeint ist pro Callsite, also bei:
Java:
public class A {
  private int a;
  class B {
    private int a;
    class C {
      private int a;
      class D {
        private int a;
        public void print() {
          System.out.println("A.a = " + A.this.a);
          System.out.println("B.a = " + B.this.a);
          System.out.println("C.a = " + C.this.a);
          System.out.println("D.a = " + D.this.a + " oder einfach " + this.a + " oder " + a);
        }
      }
    }
  }
}
kann man quasi jedes Feld "a" durch die Qualifizierung der entsprechenden gemeinten Instanz einer äußeren Klasse ansprechen.
 

Detlef Bosau

Mitglied
Da man eine Klasse mit demselben Namen nicht in sich selbst verschachtelt als innere Klasse definieren kann, also sowas geht nicht:
Java:
public class A {
  class A {}
}
ist es durch das "qualified this" dann auch wieder eindeutig, welche konkrete äußere Instanz gemeint ist pro Callsite, also bei:
Java:
public class A {
  private int a;
  class B {
    private int a;
    class C {
      private int a;
      class D {
        private int a;
        public void print() {
          System.out.println("A.a = " + A.this.a);
          System.out.println("B.a = " + B.this.a);
          System.out.println("C.a = " + C.this.a);
          System.out.println("D.a = " + D.this.a + " oder einfach " + this.a + " oder " + a);
        }
      }
    }
  }
}
kann man quasi jedes Feld "a" durch die Qualifizierung der entsprechenden gemeinten Instanz einer äußeren Klasse ansprechen.
Ich verstehe, was du meinst (und am wochenende hat es bei mir eh ziemlich gedämmert) - nur bei dem Codebeispiel könnte ich boshaft shadowing sehen. ist das verboten?
Oder - das klingt jetzt völlig wir aber logisch - ist es erlaubt und mich rettet der full qualified classname vor dem this und dann steht da eben package.Aussen.Innen.Nochweiterinnen.Gedoens.A.A.A.A.A.A.this ?

Das kann dann zwar kein Mensch mehr lesen, und du gewinnst auf jedem IOCCC den ersten Preis - aber solange dem Compiler nicht schwindelig wird, kann dir das doch egal sein.
 

httpdigest

Top Contributor
Ich lese noch keine konkrete Frage aus deinem Post raus.
Nur, dass A.A.A.A.A.this nicht geht bzw. zu gehen braucht, weil du ja - wie ich oben schon sagte - nicht eine Klasse mit demselben Namen innerhalb einer anderen Klasse mit demselben Namen deklarieren kannst.
 

M.L.

Top Contributor
package.Aussen.Innen.Nochweiterinnen.Gedoens.A.A.A.A.A.A.this
Der Code muss im Endeffekt zwar dem Compiler gefallen, aber -nach wie vor- für Menschen lesbar und verständlich sein. Man kann sich wohl den Eindruck auf dritter Seite vorstellen, wenn man den effektiven Sinn/Vorteil einer derart verschachtelten Konstruktion nicht erklären oder nachvollziehen kann .
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Nichtstatische Objekte in der paint()-Methode Java Basics - Anfänger-Themen 16
L B+Baum innere Knoten erstellen Java Basics - Anfänger-Themen 3
S Erste Schritte Innere Klassen und Interfaces Java Basics - Anfänger-Themen 2
J static verschachtelte Klassen und innere Klassen Java Basics - Anfänger-Themen 1
B Klassen Anonyme innere Klasse Java Basics - Anfänger-Themen 4
O Innere Klassen nutzen? Java Basics - Anfänger-Themen 4
F Klassen Innere Klasse - Problem Java Basics - Anfänger-Themen 2
D Annonyme Innere Klasse: Listen mit geradem Index ausgeben Java Basics - Anfänger-Themen 6
J Klassen Innere Klassen Java Basics - Anfänger-Themen 5
T Klassen Innere Klasse Java Basics - Anfänger-Themen 3
H Threads Problem bei Thread + Innere Klasse Java Basics - Anfänger-Themen 3
S Innere Klassen in Java Java Basics - Anfänger-Themen 4
A Klassen Innere Klassen, verkettete Liste Java Basics - Anfänger-Themen 9
D static, äußere/innere Klasse Java Basics - Anfänger-Themen 4
D Unterschied innere Klasse/ anonyme innere Klasse Java Basics - Anfänger-Themen 7
G innere Klassen Java Basics - Anfänger-Themen 2
G Innere Klasse static oder nicht Java Basics - Anfänger-Themen 9
berliner Klassen Vererbung und Zugriff auf innere private Variable Java Basics - Anfänger-Themen 22
M [Einfaches Beispiel] Problem mit innere Klassen Java Basics - Anfänger-Themen 4
P In innere Klassen Variablen übergeben Java Basics - Anfänger-Themen 10
S Innere Klasse, Wertübergabe (String) Java Basics - Anfänger-Themen 7
N enum als innere Klasse Java Basics - Anfänger-Themen 7
P Methode übergibt Parameter an innere Methode Java Basics - Anfänger-Themen 2
T Zugriff auf innere Klasse von aussen Java Basics - Anfänger-Themen 2
M Warum können innere Klassen keine static-members haben? Java Basics - Anfänger-Themen 2
J Innere Maße des Fensters Java Basics - Anfänger-Themen 3
A innere Klassen Java Basics - Anfänger-Themen 6
G Innere klasssen unde "extends" klassen definieren, Java Basics - Anfänger-Themen 2
I @Inject in normaler Klasse? Java Basics - Anfänger-Themen 4
P Enum oder normale Klasse? Java Basics - Anfänger-Themen 10
P Meldung aus Java-Klasse in Thread an aufrufende Klasse Java Basics - Anfänger-Themen 1
P Wie kann ich meine Keylistener Klasse unterscheiden lassen, von welcher "Quelle" der Input kommt? Java Basics - Anfänger-Themen 2
Simon16 Java ArrayListe von einer Klasse sortieren Java Basics - Anfänger-Themen 2
Amina556 Eigene Klasse definieren Java Basics - Anfänger-Themen 9
berserkerdq2 Intelij, wie kann ich einstellen, dass die aktuelle Klasse ausgeführt wird, wenn ich aufs Startsymbol drücke, gibts da eine Tastenkombination? Java Basics - Anfänger-Themen 11
M Klasse in Runden Klammern bei Objektimplementierung Java Basics - Anfänger-Themen 4
J Klassen Klasse als Komponententyp bei Feldern Java Basics - Anfänger-Themen 2
J Klassen Instanzen einer Klasse in einer anderen unabhängigen Klasse nutzen Java Basics - Anfänger-Themen 4
C Unbekannte Methode add bei Klasse die JTree erweitert Java Basics - Anfänger-Themen 14
Soranix Erste Schritte Struktur als Anfänger // Von einer Klasse auf ein Objekt einer anderen Klasse zugreifen. Java Basics - Anfänger-Themen 6
J Zugriff auf eine 2. Klasse die per UI-Designer erstellt wurde Java Basics - Anfänger-Themen 1
B Wie kann ich folgende Klasse/Methode per Button ausführen? Java Basics - Anfänger-Themen 1
B Klasse statisch erstellen da n-mal geladen Java Basics - Anfänger-Themen 3
T Meine Klasse wird nicht gefunden Java Basics - Anfänger-Themen 1
XWing Random Punkte erstellen mit der Random klasse Java Basics - Anfänger-Themen 15
_user_q Wie eine Methode/Funktion aus einer Klasse mit Constructor aufrufen? Java Basics - Anfänger-Themen 20
frager2345 Optional Klasse Java Java Basics - Anfänger-Themen 2
frager2345 Singleton-Muster Java ->Nur eine Instanz einer Klasse erzeugen können Java Basics - Anfänger-Themen 45
H Klassen Typ und Intitialisierungs-Klasse, wer bestimmt was? Java Basics - Anfänger-Themen 1
P Array vom Typ Klasse Java Basics - Anfänger-Themen 18
T Thread beenden aus zweiter Klasse Java Basics - Anfänger-Themen 4
frager2345 Java Klasse Buch verwalten Java Basics - Anfänger-Themen 0
frager2345 Java eigen Klasse zum verwalten von Büchern Java Basics - Anfänger-Themen 3
T Zugriff auf Control anderer Klasse Java Basics - Anfänger-Themen 5
H Compiler-Fehler Klasse in einem Package wird nicht gefunden bzw. akzeptiert Java Basics - Anfänger-Themen 12
B Attribute eines Objekts einer Klasse durch statische Methode einer 2. Klasse ändern? Java Basics - Anfänger-Themen 32
berserkerdq2 Habe eine Klasse, welche public ist, diese hat eine public Methode, die nicht static ist. Wenn ich nun versuche aufzurufen Probleme? Java Basics - Anfänger-Themen 8
berserkerdq2 Zwei Klassen Erben von der Klasse A, die eine Klasse kann ich an Methoden übergeben, die als Parameter A haben, die andere nicht? Java Basics - Anfänger-Themen 3
G zwei Instanzen einer Klasse Java Basics - Anfänger-Themen 29
C Int an andere Klasse übergeben Java Basics - Anfänger-Themen 26
sserio Wie kann man nach einer Klasse fragen? Java Basics - Anfänger-Themen 12
B Klasse "Character" Java Basics - Anfänger-Themen 2
F Suche nach betreuender Person für eine Jahresarbeit der 12. Klasse. Java Basics - Anfänger-Themen 6
H Mit setter-Methode JLabel in einer andern Klasse ändern. Java Basics - Anfänger-Themen 40
U Warum kann ich, auf private Variablen zugreifen, wenn ich ein Objekt in der Klasse, die private Variablen hat erstelle und dort drauf zugreifen will? Java Basics - Anfänger-Themen 7
U Warum kann ich die Methode in der ENUM Klasse nicht aufrufen? Und warum geht die Switch nicht? Java Basics - Anfänger-Themen 8
D Array in Main Methode aus anderer Klasse aufrufen Java Basics - Anfänger-Themen 3
I Array Länge in Klasse festlegen Java Basics - Anfänger-Themen 1
L Klassen Vektor Klasse Java Basics - Anfänger-Themen 2
I Interface von einer EJB Klasse, um Code zu reduzieren Java Basics - Anfänger-Themen 1
M Interface als Parameter einer Klasse Java Basics - Anfänger-Themen 8
M Wie kann ich eine Methode aus einem Interface in eine Klasse implementieren, so dass sie ihre Funktion ausführt? Java Basics - Anfänger-Themen 7
Igig1 Welche Werte sind als default Werte in einem Array, der als Datentyp eine Klasse hat? Java Basics - Anfänger-Themen 1
X Was ist der Unterschied zwischen materialisierten und nichtmaterialisierten Attributen einer Klasse? Java Basics - Anfänger-Themen 1
W Klasse existiert prüfen Java Basics - Anfänger-Themen 5
U Wie ein Attribut von einer Klassenmethode in der Klasse speichern= Java Basics - Anfänger-Themen 2
O Wie erstelle ich eine Instanz in einer Klasse für die ich die Instanz will? Java Basics - Anfänger-Themen 4
W Verschiedene Methoden in einer Klasse in der Main aufrufen? Java Basics - Anfänger-Themen 8
M Eclipse kennt keine String Klasse mehr Java Basics - Anfänger-Themen 1
M Frage zur Methode split der Klasse String Java Basics - Anfänger-Themen 32
J Fehler bei array aus anderer Klasse Java Basics - Anfänger-Themen 3
D Einen boolischen Wert aus einer Methode in einer anderen Klasse aufrufen? Java Basics - Anfänger-Themen 11
W n verschiedene Arrays zufällig ausgeben - mit der Random-Klasse? Java Basics - Anfänger-Themen 8
R TreeSet Zugriff aus anderer Klasse Java Basics - Anfänger-Themen 8
C Auf die Methode einer anderen Klasse zugreifen Java Basics - Anfänger-Themen 1
B Static Attribute in einer Klasse, wie geht das? :O Java Basics - Anfänger-Themen 19
M Von einem Menü Methode aus anderer Klasse ausführen, die errechnete Werte in Datei schreibt. Java Basics - Anfänger-Themen 8
KogoroMori21 Objektvariable anderer Klasse übernehmen, Getter/Setter Java Basics - Anfänger-Themen 11
Vivien Auf eine Variable von einer anderen Klasse aus zugreifen Java Basics - Anfänger-Themen 3
M Aufruf von statischen Methoden einer anderen Klasse Java Basics - Anfänger-Themen 15
tony241188 Implementieren Sie die Klasse Hersteller, welche die folgenden Elektrogeräte produziert Java Basics - Anfänger-Themen 3
J Junit4 Klasse erstellen Java Basics - Anfänger-Themen 5
T Auf Instanz der selben Klasse aus überschriebener Methode in Methode zugreifen. Java Basics - Anfänger-Themen 2
M Scanner Klasse Java Basics - Anfänger-Themen 4
L Meine erste eigene Exception Klasse Java Basics - Anfänger-Themen 10
E Warum lässt sich eine Klasse nicht starten, wenn eine andere Klasse in dem Modul fehlerhaft ist? Java Basics - Anfänger-Themen 1
CptK Vererbung Attributtyp in Super-Klasse noch nicht festlegen Java Basics - Anfänger-Themen 1
P Wie rufe ich Methoden mit einer Referenz auf eine Klasse||Objekt auf Java Basics - Anfänger-Themen 4
I JaxB und Klasse "Object" ? Java Basics - Anfänger-Themen 7
H Quellcode Scanner Klasse Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben