Ich habe einige Referenzen gefunden ( zum Beispiel ), die vorschlagen, final
so viel wie möglich zu verwenden, und ich frage mich, wie wichtig das ist. Dies geschieht hauptsächlich im Zusammenhang mit Methodenparametern und lokalen Variablen, nicht mit endgültigen Methoden oder Klassen. Für Konstanten ist dies offensichtlich sinnvoll.
Einerseits kann der Compiler einige Optimierungen vornehmen und macht die Absicht des Programmierers klarer. Auf der anderen Seite wird die Ausführlichkeit erhöht, und die Optimierungen können trivial sein.
Ist es etwas, an das ich mich erinnern sollte?
Antworten:
Bessesen von:
Betrachten Sie, aber verwenden Sie mit Bedacht:
Ignorieren, es sei denn, Sie fühlen sich anal:
Methodenparameter und lokale Variablen - Ich mache das selten, weil ich faul bin und finde, dass es den Code unübersichtlich macht. Ich gebe voll und ganz zu, dass das Markieren von Parametern und lokalen Variablen, die ich nicht ändern werde, "richtiger" ist. Ich wünschte, es wäre die Standardeinstellung. Aber das ist es nicht und ich finde den Code schwieriger zu verstehen, wenn das Finale vorbei ist. Wenn ich in einem anderen Code bin, werde ich ihn nicht herausziehen, aber wenn ich neuen Code schreibe, werde ich ihn nicht einfügen. Eine Ausnahme ist der Fall, in dem Sie etwas Endgültiges markieren müssen, damit Sie darauf zugreifen können es aus einer anonymen inneren Klasse.
Bearbeiten: Beachten Sie, dass ein Anwendungsfall, in dem endgültige lokale Variablen tatsächlich sehr nützlich sind, wie von @ adam-gent erwähnt, darin besteht, dass der Variable in den Zweigen
if
/ ein Wert zugewiesen wirdelse
.quelle
final
standardmäßig fast alle Klassen . Möglicherweise bemerken Sie die Vorteile nur, wenn Sie eine wirklich moderne Java-IDE verwenden (dh IDEA).final
Klassen / Methoden erkennen können. Wenn beispielsweise eine endgültige Methode deklariert, eine aktivierte Ausnahme auszulösen, diese jedoch nie auslöst, teilt Ihnen IDEA dies mit, und Sie können die Ausnahme aus derthrows
Klausel entfernen . Manchmal finden Sie auch ganze Methoden, die nicht verwendet werden. Dies ist erkennbar, wenn sie nicht überschrieben werden können.Nein, wenn Sie Eclipse verwenden, da Sie eine Speicheraktion so konfigurieren können, dass diese endgültigen Modifikatoren automatisch für Sie hinzugefügt werden . Dann erhalten Sie die Vorteile für weniger Aufwand.
quelle
Die Entwicklungszeitvorteile von "final" sind mindestens so bedeutend wie die Laufzeitvorteile. Es informiert zukünftige Redakteure des Codes über Ihre Absichten.
Das Markieren einer Klasse als "endgültig" zeigt an, dass Sie sich beim Entwerfen oder Implementieren der Klasse nicht bemüht haben, die Erweiterung ordnungsgemäß zu handhaben. Wenn die Leser Änderungen an der Klasse vornehmen können und den Modifikator "final" entfernen möchten, können sie dies auf eigenes Risiko tun. Es liegt an ihnen, sicherzustellen, dass die Klasse die Erweiterung gut handhabt.
Das Markieren einer Variablen "final" (und das Zuweisen im Konstruktor) ist bei der Abhängigkeitsinjektion hilfreich. Es zeigt die "Kollaborateur" -Natur der Variablen an.
Das Markieren einer Methode als "final" ist in abstrakten Klassen nützlich. Es wird klar umrissen, wo sich die Erweiterungspunkte befinden.
quelle
Ich benutze die
final
ganze Zeit, um Java ausdrucksbasierter zu machen. Siehe Javas Bedingungen (if,else,switch
) sind nicht ausdrucksbasiert, was ich immer gehasst habe, besonders wenn Sie an funktionale Programmierung gewöhnt sind (dh ML, Scala oder Lisp).Daher sollten Sie versuchen, (IMHO) immer endgültige Variablen zu verwenden, wenn Sie Bedingungen verwenden.
Lassen Sie mich Ihnen ein Beispiel geben:
Wenn Sie eine weitere
case
Anweisung hinzufügen und nicht festlegen,name
schlägt der Compiler fehl. Der Compiler schlägt auch fehl, wenn Sie nicht in jedem Fall brechen (dass Sie die Variable festlegen). Auf diese Weise können Sie Java denlet
Ausdrücken von Lisp sehr ähnlich machen und es so gestalten, dass Ihr Code nicht massiv eingerückt wird (aufgrund von lexikalischen Gültigkeitsbereichsvariablen).Und wie @Recurse feststellte (aber anscheinend -1 me), können Sie das Vorhergehende tun
String name
final
, ohne den Compilerfehler zu erhalten (von dem ich nie gesagt habe, dass Sie es nicht können), aber Sie könnten den Compilerfehler leicht verschwinden lassen, indem Sie den Namen nach dem Wechsel einstellen Anweisung, die die Ausdruckssemantik wegwirft oder schlimmer noch vergisst,break
dass Sie keinen Fehler verursachen können (trotz der Aussagen von @Recurse), ohne Folgendes zu verwendenfinal
:Aufgrund des Namens der Fehlereinstellung (abgesehen davon,
break
dass ich auch einen anderen Fehler vergessen habe ) kann ich dies jetzt versehentlich tun:Die letzte Variable erzwingt eine einzelne Bewertung des Namens. Ähnlich wie eine Funktion mit einem Rückgabewert immer einen Wert zurückgeben muss (Ausnahmen ignorieren), muss der Namenswechselblock den Namen auflösen und somit an den Schalterblock gebunden sein, der das Refactoring von Codeabschnitten erleichtert (dh Eclipe-Refactor: Extraktionsmethode). .
Das obige in OCaml:
Das
match ... with ...
wertet wie eine Funktion dh Ausdruck aus. Beachten Sie, wie es mit unserer switch-Anweisung aussieht.Hier ist ein Beispiel in Schema (Schläger oder Huhn):
quelle
else if (...)
in ein verwandelteif(...)
und so die Variable zurücksetzte. Ich habe ihm gezeigt, dass dies mit einer endgültigen Variablen niemals passiert wäre. Grundsätzlichfinal
zwingt Sie, die Variable einmal und nur einmal zuzuweisen ... also: PIch habe festgestellt, dass das Markieren von Methodenparametern und Einheimischen als
final
Refactoring-Hilfe nützlich ist, wenn die betreffende Methode mehrere Seiten lang ein unverständliches Durcheinander ist. Streuen Siefinal
großzügig, um zu sehen, welche Fehler der Compiler (oder Ihre IDE) der endgültigen Variablen nicht zuweisen kann, und Sie werden möglicherweise feststellen, warum die Variable "data" null wird, obwohl mehrere (veraltete) Kommentare dies schwören nicht passieren.Anschließend können Sie einige der Fehler beheben, indem Sie die wiederverwendeten Variablen durch neue Variablen ersetzen, die näher am Verwendungsort deklariert wurden. Dann können Sie ganze Teile der Methode in Klammern einschließen, und plötzlich sind Sie einen IDE-Tastendruck von "Extract Method" entfernt, und Ihr Monster ist gerade noch verständlicher geworden.
Wenn Ihre Methode nicht bereits ein nicht wartbares Wrack ist, könnte es sinnvoll sein, Dinge endgültig zu machen, um die Leute davon abzuhalten, sie in das Wrack zu verwandeln. Wenn es sich jedoch um eine kurze Methode handelt (siehe: nicht nicht wartbar), besteht die Gefahr, dass Sie viel Ausführlichkeit hinzufügen. Insbesondere Java-Funktionssignaturen sind schwer genug, um in 80 Zeichen zu passen, ohne sechs weitere pro Argument hinzuzufügen!
quelle
final
vor jedem Parameter besser .Nun, das hängt alles von Ihrem Stil ab. Wenn Sie das Finale sehen möchten, wenn Sie die Variable nicht ändern, verwenden Sie es. Wenn Sie es nicht mögen, dann lassen Sie es weg.
Ich persönlich mag so wenig Ausführlichkeit wie möglich, daher vermeide ich es, zusätzliche Schlüsselwörter zu verwenden, die nicht wirklich notwendig sind.
Ich bevorzuge jedoch dynamische Sprachen, daher ist es wahrscheinlich keine Überraschung, dass ich Ausführlichkeit vermeiden möchte.
Also würde ich sagen, wählen Sie einfach die Richtung, in die Sie sich neigen, und gehen Sie einfach damit um (versuchen Sie auf jeden Fall, konsequent zu sein).
Als Randnotiz habe ich an Projekten gearbeitet, die ein solches Muster verwenden und nicht verwenden, und ich habe keinen Unterschied in der Anzahl der Fehler oder Fehler gesehen ... Ich denke nicht, dass es ein Muster ist, das enorm sein wird Verbessern Sie die Anzahl Ihrer Fehler oder ähnliches, aber es ist wieder Stil. Wenn Sie die Absicht zum Ausdruck bringen möchten, dass Sie ihn nicht ändern, verwenden Sie ihn.
quelle
Bei Parametern ist es hilfreich, eine versehentliche Änderung des Parameterwerts zu vermeiden und einen subtilen Fehler einzuführen. Ich ignoriere diese Empfehlung, aber nachdem ich ungefähr 4 Stunden verbracht habe. In einer schrecklichen Methode (mit Hunderten von Codezeilen und mehreren Fors, verschachtelten Ifs und allen möglichen schlechten Praktiken) würde ich Ihnen empfehlen, dies zu tun.
Natürlich würde dies in einer perfekten Welt nicht passieren, aber ... nun ... manchmal muss man anderen Code unterstützen. :((
quelle
Wenn Sie eine Anwendung schreiben, bei der jemand den Code beispielsweise nach 1 Jahr lesen muss, verwenden Sie die Variable final on, die nicht ständig geändert werden sollte. Auf diese Weise wird Ihr Code "selbstdokumentierender" und Sie verringern auch die Wahrscheinlichkeit für andere Entwickler, alberne Dinge wie die Verwendung einer lokalen Konstante als lokale temporäre Variable zu tun.
Wenn Sie einen Wegwerfcode schreiben, müssen Sie nicht alle Konstanten identifizieren und endgültig machen.
quelle
Ich werde final so viel wie möglich verwenden. Dies wird angezeigt, wenn Sie das Feld unbeabsichtigt ändern. Ich habe auch die Methodenparameter auf final gesetzt. Dabei habe ich mehrere Fehler in Code entdeckt, den ich übernommen habe, als sie versuchten, einen Parameter zu setzen, der vergisst, dass Java als Wert übergeben wird.
quelle
Aus der Frage geht nicht hervor, ob dies offensichtlich ist, aber das Festlegen eines Methodenparameters wirkt sich nur auf den Hauptteil der Methode aus. Es werden dem Aufrufer KEINE interessanten Informationen über die Absichten der Methode übermittelt. Das übergebene Objekt kann weiterhin innerhalb der Methode mutiert werden (Finale sind keine Konstanten), und der Bereich der Variablen liegt innerhalb der Methode.
Um Ihre genaue Frage zu beantworten, würde ich mir nicht die Mühe machen, eine Instanz oder eine lokale Variable (einschließlich Methodenparameter) endgültig zu machen, es sei denn, der Code erfordert dies (z. B. die Variable wird von einer inneren Klasse referenziert) oder eine wirklich komplizierte Logik zu klären.
Zum Beispiel würde ich Variablen endgültig machen, wenn sie logisch konstant sind.
quelle
Es gibt viele Verwendungszwecke für die Variable
final
. Hier sind nur einigeEndkonstanten
Dies kann dann für andere Teile Ihres Codes verwendet werden oder von anderen Klassen aufgerufen werden. Wenn Sie den Wert jemals ändern würden, müssten Sie sie nicht einzeln ändern.
Letzte Variablen
In dieser Klasse erstellen Sie eine endgültige Variable mit Gültigkeitsbereich, die dem Parameter environmentKey ein Präfix hinzufügt. In diesem Fall ist die endgültige Variable nur innerhalb des Ausführungsbereichs endgültig, der bei jeder Ausführung der Methode unterschiedlich ist. Bei jeder Eingabe der Methode wird das Finale rekonstruiert. Sobald es erstellt wurde, kann es im Rahmen der Methodenausführung nicht mehr geändert werden. Auf diese Weise können Sie eine Variable in einer Methode für die Dauer der Methode festlegen. siehe unten:
Endkonstanten
Diese sind besonders nützlich, wenn Sie wirklich lange Codezeilen haben und sie einen Compilerfehler erzeugen, sodass Sie nicht auf Logik- / Geschäftsfehler stoßen, wenn jemand versehentlich Variablen ändert, die nicht geändert werden sollten.
Endgültige Sammlungen
In einem anderen Fall, wenn es sich um Sammlungen handelt, müssen Sie sie als nicht modifizierbar festlegen.
Andernfalls, wenn Sie es nicht als nicht änderbar festlegen:
Final Classes und Final Methods können nicht erweitert bzw. überschrieben werden.
BEARBEITEN: UM DAS ENDGÜLTIGE KLASSENPROBLEM IN BEZUG AUF DIE ENKAPSULATION ZU BEHEBEN:
Es gibt zwei Möglichkeiten, ein Klassenfinale zu erreichen. Das erste besteht darin, das Schlüsselwort final in der Klassendeklaration zu verwenden:
Die zweite Möglichkeit, ein Klassenfinale zu erreichen, besteht darin, alle Konstruktoren als privat zu deklarieren:
Wenn Sie es als endgültig markieren, sparen Sie sich die Mühe, wenn Sie feststellen, dass es sich tatsächlich um ein Finale handelt, um einen Blick auf diese Testklasse zu werfen. sieht auf den ersten Blick öffentlich aus.
Da der einzige Konstruktor der Klasse privat ist, ist es leider unmöglich, diese Klasse zu erweitern. Im Fall der Testklasse gibt es keinen Grund, warum die Klasse endgültig sein sollte. Die Testklasse ist ein gutes Beispiel dafür, wie implizite Abschlussklassen Probleme verursachen können.
Sie sollten es also als endgültig markieren, wenn Sie eine Klasse implizit endgültig machen, indem Sie ihren Konstruktor privat machen.
quelle
Wie Sie bereits erwähnt haben, ein Kompromiss, aber ich bevorzuge die explizite Verwendung von etwas gegenüber der impliziten Verwendung. Dies wird dazu beitragen, einige Unklarheiten für zukünftige Codeverwalter zu beseitigen - selbst wenn es nur Sie sind.
quelle
Wenn Sie innere (anonyme) Klassen haben und die Methode auf die Variable der enthaltenen Methode zugreifen muss, müssen Sie diese Variable als endgültig haben.
Davon abgesehen ist das, was Sie gesagt haben, richtig.
quelle
Verwenden Sie das
final
Schlüsselwort für eine Variable, wenn Sie diese Variable als erstellenimmutable
Durch das Deklarieren der Variablen als endgültig können Entwickler mögliche Änderungsprobleme von Variablen in einer Umgebung mit mehreren Multithreads ausschließen.
Mit Java 8 haben wir ein weiteres Konzept namens "
effectively final variable
". Eine nicht endgültige Variable kann als endgültige Variable angehoben werden.Lokale Variablen, auf die aus einem Lambda-Ausdruck verwiesen wird, müssen endgültig oder effektiv endgültig sein
Bis Java 7 können Sie keine nicht endgültige lokale Variable in einer anonymen Klasse verwenden, aber von Java 8 aus
Schauen Sie sich diesen Artikel an
quelle
Zunächst wird das letzte Schlüsselwort verwendet, um eine Variable konstant zu machen. Konstante bedeutet, dass es sich nicht ändert. Beispielsweise:
Sie würden die Variable final deklarieren, da sich ein Zentimeter pro Zoll nicht ändert.
Wenn Sie versuchen, einen Endwert zu überschreiben, wurde die Variable zuerst deklariert. Beispielsweise:
Es gibt einen Kompilierungsfehler, der ungefähr so aussieht:
Wenn Ihre Variable nicht als endgültig deklariert werden kann oder wenn Sie sie nicht als endgültig deklarieren möchten, versuchen Sie Folgendes:
Dies wird gedruckt:
quelle