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.
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.
Tags und Links java