Warum funktioniert die Referenzierung einer anonymen inneren Klasse nach ihrem Namen, wenn sie Mitglied ist, aber keine Variable?

8

Entschuldigung für den Titel Gore, ich wusste nicht, wie ich das Problem in einer Zeile beschreiben sollte. Wenn Sie Vorschläge haben, bin ich offen.

Angenommen, Sie haben die folgende Klasse:

%Vor%

Warum kann die memberRunnable von run() aus auf sich selbst zugreifen, während varRunnable nicht funktioniert? AFAICS ist das exakt gleiche Konstrukt.

Sie können natürlich this stattdessen verwenden, ich weiß. Ich frage mich nur, warum der Compiler zwischen den beiden Fällen unterscheidet, die identisch erscheinen. Auch warum denkt es varRunnable wurde möglicherweise nicht initialisiert, wenn es offensichtlich ist, dass es an diesem Punkt ist.

Man könnte argumentieren, dass, wenn Runnable eine Klasse ist (es ist eine Schnittstelle), der Konstruktor versucht, run() aufzurufen, was tatsächlich zu einem Szenario führt, in dem die Referenz nicht initialisiert ist. Dies sollte jedoch auch für memberRunnable der Fall sein, aber dieser Fall funktioniert.

Komische Sache, nichts ändert sich, wenn statt Runnable eine Klasse verwendet wird, in welchem ​​Fall das obige Szenario (Konstruktor, der eine überschriebene Methode aufruft) tatsächlich passieren kann. Das bedeutet, dass Sie in diesem Fall zur Laufzeit auf ein "nicht initialisiertes Feld" stoßen können (habe es noch nicht versucht), was ziemlich dumm ist, da der Compiler sich davor schützen sollte.

    
Felix 08.05.2015, 17:44
quelle

1 Antwort

9
  

Auch warum es denkt, dass varRunnable möglicherweise nicht initialisiert wurde, wenn es offensichtlich ist, dass es zu diesem Zeitpunkt ist.

Nein, die Variable wird nicht (im allgemeinen Fall) garantiert an diesem Punkt initialisiert.

Nehmen wir einmal an, dass Runnable eine abstrakte Klasse (und keine Schnittstelle) ist und dass der Konstruktor von Runnable this.run() heißt. Da der Aufbau von Runnable vor der Zuweisung stattfindet, würde dies zu einem Zugriff von varRunnable führen, bevor die Zuweisung stattgefunden hat.

Mit anderen Worten, es würde zum Zugriff auf eine nicht initialisierte lokale Variable führen. Beachten Sie, dass dies schlechter ist als der Zugriff auf ein Feld, das noch nicht explizit initialisiert wurde, da lokale Variablen nicht auf Standardwerte initialisiert werden. Es ist so viel schlimmer, dass der Zugriff auf nicht initialisierte lokale Variablen verboten ist, während der Zugriff auf Felder, die nicht explizit initialisiert wurden, erlaubt ist, wie Sie gerade herausgefunden haben. (Das Feld final zu ändern, ändert dies nicht. Endgültige Felder haben auch Standardwerte und können sich tatsächlich (einmal) im Konstruktor ändern.)

Quelle: Ich bin ein Java-Entwickler.

    
aioobe 08.05.2015, 17:47
quelle

Tags und Links