Klassisches Beispiel eines einfachen Servers:
%Vor% Warum sollte Socket
als final
deklariert werden? Liegt es daran, dass der neue Thread
, der die Anfrage bearbeitet, sich auf die socket
Variable in der Methode beziehen und eine Art von ConcurrentModificationException
?
In diesem Fall muss die Variable endgültig sein, um in der anonymen Runnable
-Implementation verwendet zu werden.
Dies liegt daran, dass das Objekt existiert, wenn die Variable bereits den Gültigkeitsbereich verlassen hat und somit verschwunden ist. Das Objekt erhält eine Kopie der Variablen. Um dies zu verbergen, muss die Variable endgültig sein, damit niemand erwarten kann, dass Änderungen in einer Kopie für die andere sichtbar sind.
Betrachten Sie dieses Beispiel:
%Vor% Wenn c nicht final war, würde es auf "join" verweisen, wenn Sie b.goo()
erreichen, da das c eine "garbage-collected" wäre - Eine lokale Variable nach dem Ende eines Methodenaufrufs / p>
Sie müssen es endgültig erklären, nicht nur. Ohne diese Angabe kann der Compiler sie nicht in der Implementierung der anonymen Runnable-Klasse verwenden.
deklariert eine Methodenvariable final bedeutet, dass ihr Wert sich nicht ändern kann; dass es nur einmal gesetzt werden kann. Wie sieht das in diesem Zusammenhang aus?
Ich kannte diese Einschränkung mit anonymen Klassen seit einiger Zeit, aber ich habe nie verstanden warum. Ich sehe, dass niemand sonst wirklich von den Antworten bis jetzt wirklich tut. Etwas googeln tauchte unten auf, was ich denke, macht es gut, es zu erklären.
Eine anonyme lokale Klasse kann lokal verwenden Variablen, weil der Compiler gibt automatisch die Klasse a privates Instanzfeld, um eine Kopie zu halten jeder lokalen Variable, die die Klasse verwendet. Der Compiler fügt auch versteckt hinzu Parameter zu jedem Konstruktor zu initialisieren diese automatisch erstellt private Felder. Also eine lokale Klasse greift tatsächlich nicht auf lokal zu Variablen, sondern nur seine eigenen privaten Kopien von ihnen. Der einzige Weg das kann richtig funktionieren ist wenn das lokale Variablen werden als final deklariert, so dass Sie werden garantiert nicht geändert. Mit dieser Garantie, die lokale Klasse ist versichert, dass es interne Kopien der Variablen genau das tatsächliche lokale widerspiegeln Variablen.
Kredit an: Ссылка
sicherlich nicht offensichtlich und etwas, das ich denke, dass der Compiler wirklich von Entwicklern versteckt werden sollte.
Lokale Variablen werden nicht zwischen Threads geteilt. (Eine lokale Variable ist ein Teil des Aktivierungsdatensatzes und jeder Thread hat seinen eigenen Aktivierungsdatensatz.)
Da connection
eine lokale Variable ist, ist es nicht möglich, sie zwischen Threads zu teilen. Da es nicht zwischen Threads geteilt wird, müssen Sie es final
machen, also spielt es keine Rolle, dass es sich um eine lokale Variable handelt (es kann mehr wie ein konstanter Wert gesehen werden).
Es ist nicht beabsichtigt, ConcurrentModificationException zu lösen. Jede lokale Variable, die in einer in der Methode geschachtelten Klasse verwendet wird (z. B. eine anonyme innere Klasse), muss als final deklariert werden. Siehe eine ähnliche Diskussion der letzten Woche hier:
method local innerclasses Zugriff auf die lokalen Variablen der Methode
Tatsächlich gibt es bei Gewinden hier einen kleinen Beitrag zur Fadensicherheit; Es wird keine Sichtbarkeitsprobleme für die letzte Variable zwischen den Threads geben. Dies garantiert jedoch keine Fadensicherheit.
Tags und Links java methods concurrency final