Wie in den Kommentaren erwähnt, ist ein Teil davon in Java 8 irrelevant, wo final
dies implizit sein kann. In einer anonymen inneren Klasse oder einem Lambda-Ausdruck kann jedoch nur eine effektiv endgültige Variable verwendet werden.
Dies liegt im Wesentlichen an der Art und Weise, wie Java Schließungen verwaltet .
Wenn Sie eine Instanz einer anonymen inneren Klasse erstellen, werden die Werte aller Variablen, die in dieser Klasse verwendet werden, über den automatisch generierten Konstruktor kopiert. Dies vermeidet, dass der Compiler verschiedene zusätzliche Typen automatisch generieren muss, um den logischen Status der "lokalen Variablen" zu speichern, wie dies beispielsweise der C # -Compiler tut ... (Wenn C # eine Variable in einer anonymen Funktion erfasst, erfasst es die Variable - die Das Schließen kann die Variable auf eine Weise aktualisieren, die vom Hauptteil der Methode gesehen wird, und umgekehrt.)
Da der Wert in die Instanz der anonymen inneren Klasse kopiert wurde, würde es seltsam aussehen, wenn die Variable durch den Rest der Methode geändert werden könnte - Sie könnten Code haben, der anscheinend mit einer veralteten Variablen funktioniert ( denn genau das würde passieren ... Sie würden mit einer Kopie arbeiten, die zu einem anderen Zeitpunkt aufgenommen wurde. Wenn Sie Änderungen innerhalb der anonymen inneren Klasse vornehmen könnten, könnten Entwickler erwarten, dass diese Änderungen im Hauptteil der einschließenden Methode sichtbar sind.
Wenn Sie die Variable final machen, werden alle diese Möglichkeiten entfernt. Da der Wert überhaupt nicht geändert werden kann, müssen Sie sich keine Gedanken darüber machen, ob solche Änderungen sichtbar sind. Die einzige Möglichkeit, der Methode und der anonymen inneren Klasse zu erlauben, die Änderungen des anderen zu sehen, besteht darin, einen veränderlichen Typ einer Beschreibung zu verwenden. Dies könnte die einschließende Klasse selbst sein, ein Array, ein veränderbarer Wrapper-Typ ... so etwas. Im Grunde ist es ein bisschen wie die Kommunikation zwischen einer Methode und einer anderen: Änderungen, die an den Parametern einer Methode vorgenommen wurden, werden vom Aufrufer nicht gesehen, aber Änderungen an den Objekten, auf die die Parameter verweisen, werden angezeigt.
Wenn Sie an einem detaillierteren Vergleich zwischen Java- und C # -Verschlüssen interessiert sind, habe ich einen Artikel, der weiter darauf eingeht. Ich wollte mich in dieser Antwort auf die Java-Seite konzentrieren :)