2015-05-28 13 views
8

Jetzt kam ich vor kurzem in eine Empfehlung, dass Sie das Schlüsselwort final so weit wie möglich verwenden sollten. Dies ist gut, um zu verhindern, dass ein Programmierer sein eigenes Bein erschießt - das heißt, er weist die Variable neu zu, die nicht neu zugewiesen werden sollte.Hat das Keyword final Auswirkungen auf die JVM?

Aber dient es einem anderen Ziel? Das heißt, kann JVM Informationen über die endgültigen Variablen verwenden, um den Bytecode irgendwie zu optimieren, damit er schneller lief (ein besseres Pipelining erstellen oder ihn in einer Multithread-Umgebung verwenden)? Oder ist nur ein syntaktischer Zucker, der die Möglichkeit von Fehlern während der Codeentwicklung minimiert?

+0

final oder Sie können konstante Hilfe in Compiler-Optimierungen sagen. zB: - Constant Folding, Constant Propagation –

+0

Verwandte: http://stackoverflow.com/questions/3961881/why-defining-class-as-final-improves-jvm-performance?rq=1 – Patrick

+0

"Oder ist nur ein syntaktischer Zucker das minimiert die Möglichkeit von Fehlern bei der Codeentwicklung? " Tatsächlicher intelligenter Gedanke minimiert Fehler. Ohne das ist das Schlusswort nicht nur syntaktischer Zucker, sondern auch ein Placebo. – Gimby

Antwort

4

IBM states:

Wie viele Mythen über Java-Leistung, den Irrglauben, dass weit verbreiteten, aber selten untersuchte Klassen oder Methoden als Endergebnisse zu einer besseren Leistung zu erklären. Das Argument besagt, dass das Deklarieren einer Methode oder Klasse als endgültig bedeutet, dass der Compiler in der Lage ist, Methodenaufrufe aggressiver auszuführen, da er weiß, dass dies zur Laufzeit definitiv die Version der Methode ist, die aufgerufen wird. Aber das ist einfach nicht wahr.Nur weil die Klasse X gegen die letzte Klasse Y kompiliert wird, heißt das nicht, dass zur Laufzeit die gleiche Version der Klasse Y geladen wird. Der Compiler kann also solche Cross-Class-Methodenaufrufe nicht sicher, endgültig oder nicht inline einbinden. Nur wenn eine Methode privat ist, kann der Compiler sie inline einfügen, und in diesem Fall wäre das endgültige Schlüsselwort redundant.

4

Soweit Variablen gehen, ist Java schlau genug, um herauszufinden, dass eine Variable nirgendwo in der Methode geändert wird, und dieses Wissen zu Optimierungszwecken verwendet. Sie müssen nicht eine Variable final markieren, um das zu wissen.

Methoden sind eine etwas andere Geschichte: Wenn Sie eine Methode final markieren, kann Java solche Methode schneller aufrufen, da es nicht mehr nach seinen Überschreibungen suchen muss. Dennoch ist der Hotspot intelligent genug, um herauszufinden, dass es keine Außerkraftsetzungen gibt, mit oder ohne die Verwendung von final.

Im Allgemeinen soll diese Empfehlung jedoch Ihren Code leichter lesbar und für andere verständlich machen: Wenn Sie eine Variable final machen, erfahren Sie, dass Sie eine Konstante erstellen. Ein Klassenabschluss macht Ihren Lesern klar, dass die Klasse nicht für die Vererbung ausgelegt ist; Wenn Sie eine Methode final machen, wird Ihren Lesern mitgeteilt, dass die Logik dieser Methode in der Vererbungshierarchie invariant bleiben soll. Auf lange Sicht sind diese Informationen wertvoller als die Möglichkeit, Ihren laufenden Code zu optimieren.

+0

Was ist mit privaten Methoden? Brauchen sie ein endgültiges Schlüsselwort? Schließlich können sie definitiv nicht außer Kraft gesetzt werden. –

+0

@ SPIRiT_1984 'private' Methoden müssen nicht mit' final' markiert werden - sie profitieren von der gleichen Optimierung wie die finalen Methoden ('statische' Methoden bekommen das auch, weil sie in Java nicht überschrieben werden können). – dasblinkenlight

+0

"Java" (Hotspot wirklich) ist in der Regel klug genug, um herauszufinden, ob eine Methode nie überschrieben wird und tut diese Optimierungen sowieso, also ja letzten Absatz. – Voo

1

finale Methoden können von der JVM bis zu dem Zeitpunkt, zu dem sie von der JVM geladen werden, inline ausgeführt werden. Wenn Sie also sicher sind, dass die Methode nicht neu definiert wird, markieren Sie sie als endgültig.

Konstanten sollten immer statisch final sein, da sie unveränderlich sind und jvm diese Variablen nicht verfolgen muss, da sie sich niemals ändern werden.

+0

_wenn Sie sicher sind, dass die Methode nicht neu definiert wird, markieren Sie sie als final._ Ich würde mich nie sicher sein, es sei denn, ich wüsste von einem Grund, warum die Methode _must_ nicht neu definiert werden muss (z. B. wenn sie von einem aufgerufen wird Konstrukteur). Nur weil ich keinen Grund finde, eine Methode außer Kraft zu setzen, heißt das nicht, dass ein anderer Programmierer nicht an einen Grund denkt. –

+0

@ james-groß, im Allgemeinen, wenn Sie eine Bibliothek erstellen und steuern möchten, welche Klassen und Methoden "erlaubt" überschrieben werden, gibt final Schlüsselwort Ihnen nur einen Mechanismus, dies zu tun. Das meinte ich mit meiner Aussage. – Farhad

+1

Richtig, und ich würde das niemals kontrollieren wollen, es sei denn, ich wüsste von einem speziellen Fall, wo eine Client-Überschreibung verhindern könnte, dass eine meiner Klassen sich so verhält, wie ich es versprochen habe. –

1

Ich denke, diese Empfehlung ist ein bisschen zu unspezifisch.

Zum Beispiel; Ich würde empfehlen, die Verwendung von final für Klassen und Methoden standardmäßig zu vermeiden (weil die letzten Klassen Komponententests unterbrechen).

Ich finde auch, dass die Verwendung von final für Methodenparameter nur eine Verschwendung von "Bildschirm Platz" (und damit: verschwenden "Energie" auf der Seite des Lesers).

Auf der anderen Seite, mit nur endgültige Attribute für Klassen können Objekte solcher Klassen in unveränderliche Dinger drehen; und das ist eine gute Sache.

Wie Sie sehen; Es gibt viele Vor- und Nachteile bei der Verwendung von final; und ich denke, dass "Lesbarkeit" meistens "potenzielle" Leistungsverbesserungen gewinnt.

Verwandte Themen