Verwenden des Modifikators "final", wann immer dies in Java anwendbar ist [geschlossen]


194

In Java gibt es die Praxis, jede Variable (lokal oder Klasse) als Parameter final zu deklarieren, wenn dies tatsächlich der Fall ist.

Dies macht den Code zwar viel ausführlicher, erleichtert jedoch das Lesen / Erfassen des Codes und verhindert Fehler, da die Absicht klar gekennzeichnet ist.

Was denkst du darüber und was folgst du?


13
Dies kann zu einem religiösen Streit führen. Manche Leute mögen es, manche hassen es. Ich mag endgültige Felder, aber keine endgültigen lokalen Variablen, es sei denn, sie müssen es sein, ich bin mir nicht sicher, ob sie völlig rational sind. Ich bin mir nicht sicher, ob es eine Ablehnung geben würde. Ich stimme Alex Miller zu. ;)
Peter Lawrey

Ich kann verstehen, wenn die Leute nicht möchten, dass ihr Code mit dem Finale überfüllt ist. Aber dies ist ein Problem, das ein guter Editor lösen könnte: bugs.eclipse.org/bugs/show_bug.cgi?id=409379
oberlies

Antworten:


184

Ich denke, das hat alles mit einem guten Codierungsstil zu tun. Natürlich können Sie gute, robuste Programme schreiben, ohne finalirgendwo viele Modifikatoren zu verwenden, aber wenn Sie darüber nachdenken ...

Das Hinzufügen finalzu allen Dingen, die sich nicht ändern sollten, schränkt lediglich die Möglichkeiten ein, dass Sie (oder der nächste Programmierer, der an Ihrem Code arbeitet) den Denkprozess, der zu Ihrem Code geführt hat, falsch interpretieren oder missbrauchen. Zumindest sollte es einige Glocken läuten, wenn sie jetzt Ihr zuvor unveränderliches Ding ändern wollen.

Zuerst sieht es etwas umständlich aus, viele finalSchlüsselwörter in Ihrem Code zu sehen, aber schon bald werden Sie das Wort selbst nicht mehr bemerken und einfach denken, dass sich das Ding von diesem Punkt an nie ändern wird. auf (du kannst es mir nehmen ;-)

Ich denke, es ist eine gute Praxis. Ich benutze es nicht die ganze Zeit, aber wenn ich kann und es Sinn macht, etwas zu beschriften, finalwerde ich es tun.


16
Anstatt das letzte Schlüsselwort für Parameter zu verwenden, können Sie ein statisches Analysetool wie FindBugs verwenden, um zu verlangen, dass Parametervariablen nicht neu zugewiesen werden. Auf diese Weise entfernen Sie die syntaktische Belastung und können sie über eine FindBugs-Prüfung in Ihrem Continuous Integration Tool erzwingen.
Timo Westkämper

20
@ Timo Dies würde funktionieren, hat aber den Nachteil, dass dies nach dem Einchecken überprüft werden muss und nicht, während der Entwickler am Code arbeitet. Für final, der Compiler wird offensichtlich nicht , weiterzumachen , wenn Sie einen Fehler machen.
Mike

9
Eclipse bietet die Möglichkeit, beim finalSpeichern nach Möglichkeit (Variablen, die sich nicht ändern) hinzuzufügen .
Bert F

22
+1 Ich liebe final. Es macht 98% der Zeit keinen Unterschied, es ist eine kleine Unannehmlichkeit% 1 der Zeit, aber die 1% der Zeit erspart mir, etwas Dummes oder Unbeabsichtigtes zu tun, das ist es wert.
Bert F

14
@ BertF Ja, ich lasse Eclipse immer finalüberall Modifikatoren hinzufügen , wenn ich meinen Code " bereinige ...". Überall bedeutet sogar in catch () -Blöcken, und wie gesagt, Sie werden sie nach einer Weile nicht mehr bemerken. Wenn ich eine Sprache erstellen würde, finalwäre dies natürlich die Standardeinstellung und ein varoder modifiabledas optionale Schlüsselwort.
Maarten Bodewes

191

Bessesen von:

  • Endgültige Felder - Wenn Sie Felder als endgültig markieren, müssen sie bis zum Ende der Konstruktion festgelegt werden, sodass diese Feldreferenz unveränderlich ist. Dies ermöglicht die sichere Veröffentlichung von Feldern und vermeidet die Notwendigkeit einer Synchronisation bei späteren Lesevorgängen. (Beachten Sie, dass für eine Objektreferenz nur die Feldreferenz unveränderlich ist - Dinge, auf die sich die Objektreferenz bezieht, können sich noch ändern und dies wirkt sich auf die Unveränderlichkeit aus.)
  • Endgültige statische Felder - Obwohl ich jetzt in vielen Fällen, in denen ich statische endgültige Felder verwendet habe, Aufzählungen verwende.

Betrachten Sie, aber verwenden Sie mit Bedacht:

  • Letzte Klassen - Framework / API-Design ist der einzige Fall, in dem ich es betrachte.
  • Endgültige Methoden - Grundsätzlich gleich wie Abschlussklassen. Wenn Sie Muster für Vorlagenmethoden wie "Verrückt" und "Endgültiges Markieren" verwenden, verlassen Sie sich wahrscheinlich zu sehr auf die Vererbung und nicht genug auf die Delegierung.

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.

8
Beste Antwort bisher über mehrere Fragen zu diesem letzten Thema
Gabriel Ščerbák

4
Die meiste Zeit, wenn ich eine lokale Variable ohne das letzte Wort davor sehe und sie dort nicht verwendet werden kann, sagt sie mir, dass ich wahrscheinlich Code in einer neuen Methode extrahieren sollte, die den gewünschten Wert zurückgibt, den ich endgültig machen werde. Die Fälle, in denen dies nicht zutrifft, sind, wenn ich einige Streams verwende oder wenn ich versuchen muss, sie abzufangen.
Nyxz

32

Sie müssen wirklich die vollständige Verwendung des endgültigen Schlüsselworts verstehen, bevor Sie es verwenden können. Es kann auf Variablen, Felder, Methoden und Klassen angewendet werden und hat unterschiedliche Auswirkungen darauf

Ich würde empfehlen, den unten verlinkten Artikel für weitere Details zu lesen.

Letztes Wort zum letzten Schlüsselwort


29

Der finalModifikator, insbesondere für Variablen, ist ein Mittel, mit dem der Compiler eine Konvention erzwingen kann, die im Allgemeinen sinnvoll ist: Stellen Sie sicher, dass eine (lokale oder Instanz-) Variable genau einmal zugewiesen wird (nicht mehr und nicht weniger). Indem Sie sicherstellen, dass eine Variable definitiv zugewiesen ist, bevor sie verwendet wird, können Sie häufige Fälle von a vermeiden NullPointerException:

final FileInputStream in;
if(test)
  in = new FileInputStream("foo.txt");
else
  System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned

Indem Sie verhindern, dass eine Variable mehr als einmal zugewiesen wird, verhindern Sie das Scoping im Ausland. An Stelle von:

 String msg = null;
 for(int i = 0; i < 10; i++) {
     msg = "We are at position " + i;
     System.out.println(msg);
 }
 msg = null;

Sie werden aufgefordert, dies zu verwenden:

 for(int i = 0; i < 10; i++) {
     final String msg = "We are at position " + i;
     System.out.println(msg);
 }

Einige Links:


1
+1 für entmutigen Overbroad Scoping Argument
Tom Tresansky

Kurz gesagt kann man im Grunde können Sie verwenden , finalum Java mehr Ausdruck basiert zu machen .
Adam Gent

"Wenn Sie sicherstellen, dass eine Variable definitiv zugewiesen ist, bevor sie verwendet wird, können Sie häufige Fälle einer NullPointerException vermeiden:" Dies ist nicht korrekt. 'Final' macht hier keinen Unterschied. Der Compiler kennt und beschwert sich möglicherweise über die Variable 'in' im angegebenen Beispiel null sein.
Nyholku

@nyholku Sie haben Recht, in Java müssen lokale Variablen vor der Verwendung definitiv zugewiesen werden, auch ohne final. Aber für Felder braucht man das Finale. In einem etwas komplexeren Beispiel, in dem "in" eine Instanzvariable einer Klasse ist und das if / else im Konstruktor enthalten ist, benötigen Sie das Finale, um das Problem zu signalisieren. Darüber hinaus gibt es auch für lokale Variablen einen Wert in der endgültigen IMO, da dies verhindert, dass der schlampige Programmierer den Kompilierungsfehler über "in", der möglicherweise nicht zugewiesen ist, durch Hinzufügen von "= null" zu seiner Deklaration "behebt". Mit anderen Worten, nach meiner Erfahrung reduzieren endgültige Variablen die Verwendung von Null.
Bruno De Fraine

20

Ich bin ziemlich dogmatisch, wenn es darum geht, jede mögliche Variable zu deklarieren final. Dies umfasst Methodenparameter, lokale Variablen und selten Wertobjektfelder. Ich habe drei Hauptgründe, um überall endgültige Variablen zu deklarieren:

  1. Absichtserklärung: Mit der Deklaration einer endgültigen Variablen erkläre ich, dass diese Variable nur einmal geschrieben werden soll. Es ist ein subtiler Hinweis für andere Entwickler und ein großer Hinweis für den Compiler.
  2. Durchsetzen von Einwegvariablen: Ich glaube an die Idee, dass jede Variable nur einen Lebenszweck haben sollte. Indem Sie jeder Variablen nur einen Zweck geben, reduzieren Sie die Zeit, die erforderlich ist, um den Zweck dieser bestimmten Variablen beim Debuggen zu ermitteln.
  3. Ermöglicht die Optimierung: Ich weiß, dass der Compiler früher Tricks zur Leistungssteigerung hatte, die sich speziell auf die Unveränderlichkeit einer Variablenreferenz stützten. Ich denke gerne, dass einige dieser alten (oder neuen) Performance-Tricks vom Compiler verwendet werden.

Ich denke jedoch, dass endgültige Klassen und Methoden bei weitem nicht so nützlich sind wie endgültige Variablenreferenzen. Das finalSchlüsselwort, wenn sie mit diesen Erklärungen verwendet einfach zur Verfügung stellen Hindernisse für automatisierte Tests und die Verwendung des Codes in einer Weise , dass man nie erwartet hätte.


2
finalVariablen und Methodenparameter haben keinen Einfluss auf die Leistung, da sie nicht im Bytecode ausgedrückt werden.
Steve Kuo

Variable: = Latein: Varius> verschiedene> modifizierbar
Dieter

17

Effektives Java hat ein Element mit der Aufschrift "Unveränderliche Objekte bevorzugen". Wenn Sie Felder als endgültig deklarieren, können Sie einige kleine Schritte in diese Richtung unternehmen, aber wirklich unveränderliche Objekte bieten natürlich noch viel mehr.

Wenn Sie wissen, dass Objekte unveränderlich sind, können sie ohne Synchronisierungsprobleme zum Lesen für viele Threads / Clients freigegeben werden, und es ist einfacher, über die Ausführung des Programms nachzudenken.


15
vorsichtig - endgültig und unveränderlich sind völlig unterschiedliche Konzepte. Es ist einfach, ein endgültiges veränderbares Objekt zu haben - bei final geht es um die Referenz, bei der Veränderlichkeit um die Objektinstanz. letzte Person olaf = neue Person (); olaf.setName ("Olaf");
Olaf Kock

1
Genau - unveränderliche Objekte sind eine Sache, unveränderliche Referenzen (dh endgültig) sind etwas ganz anderes.
SCdF

2
Sie sind jedoch eng miteinander verbunden, da Sie das Feld Person.name als final deklarieren können (und die Klasse final deklarieren und ...), um das Person-Objekt final zu machen. Es ist jedoch nicht so einfach, nur "letzte Person" zu machen ...
Sebastian Ganslandt

Dies ist auch für lokale Variablen irrelevant (Parameter sind lokale Variablen). Es gilt nur für Klassenvariablen, daher wird die Frage nur teilweise behandelt.
Robin

12

Ich war noch nie in einer Situation, in der ein endgültiges Schlüsselwort für eine Variable mich davon abgehalten hat, einen Fehler zu machen. Daher halte ich es im Moment für eine riesige Zeitverschwendung.

Wenn es keinen wirklichen Grund dafür gibt (wie in einem bestimmten Punkt, dass diese Variable endgültig ist), würde ich es lieber nicht tun, da ich finde, dass der Code dadurch weniger lesbar wird.

Wenn Sie jedoch nicht feststellen, dass der Code schwerer zu lesen oder länger zu schreiben ist, sollten Sie ihn unbedingt verwenden.

Bearbeiten: Als Klarstellung (und als Versuch, Rückstimmen zurückzugewinnen) sage ich nicht, dass Konstanten nicht als endgültig markiert werden, ich sage, dass Sie keine Dinge tun wie:

public String doSomething() {
  final String first = someReallyComplicatedExpressionToGetTheString();
  final String second = anotherReallyComplicatedExpressionToGetAnother();

  return first+second;
}

Es macht Code (meiner Meinung nach) nur schwerer zu lesen.

Es ist auch erwähnenswert, dass alles , was endgültig ist, Sie daran hindert, eine Variable neu zuzuweisen, sie nicht unveränderlich macht oder so etwas.


1
Drehen Sie die Anweisung auf dem Kopf: Ich war viele Situationen , in denen nicht mit final(und unveränderliche Objekte im Allgemeinen) haben einen bedeutenden Faktor für die Zahl und die Auswirkungen von Fehlern haben.
Chris Vest

3
Ich bin alles für unveränderliche Objekte. Ich war einfach noch nie in einer Situation, in der es mir geholfen hat, ein unveränderliches Objekt endgültig zu markieren.
SCdF

2
Ich bin damit einverstanden, dass wir final nicht für lokale Variablen und Methodenparameter verwenden sollten, da dies den Code viel weniger lesbar macht.
Rmaruszewski

@ChrisVest, vielleicht sind deine Funktionen zu lang
Pacerier

8

Final sollte immer für Konstanten verwendet werden. Es ist sogar nützlich für kurzlebige Variablen (innerhalb einer einzelnen Methode), wenn die Regeln zum Definieren der Variablen kompliziert sind.

Beispielsweise:

final int foo;
if (a)
    foo = 1;
else if (b)
    foo = 2;
else if (c)
    foo = 3;
if (d)        // Compile error:  forgot the 'else'
    foo = 4;
else
    foo = -1;

6

Klingt nach einem der größten Argumente dagegen Verwendung des endgültigen Schlüsselworts: "Es ist unnötig" und "es verschwendet Platz".

Wenn wir die vielen Vorteile von "final" anerkennen, auf die viele großartige Beiträge hier hinweisen, und gleichzeitig zugeben, dass es mehr Eingabe und Platz erfordert, würde ich argumentieren, dass Java die Variablen standardmäßig "final" hätte machen müssen und verlangen muss, dass die Dinge markiert werden. " veränderlich "wenn der Codierer es will.


1
Downvoters, möchten Sie das erklären?
RAY

Scheint seltsam, es dann eine Variable zu nennen, nicht wahr?
Alan

2
Es stehen Tausende von englischen Wörtern zur Auswahl.
RAY

Dies ist perfekt. Es gibt keine Argumente dagegen, finalaußer "zu lang zum Schreiben", "macht Code ungeschickter". Es gibt mehrere Argumente für final. Und wir können es beim Speichern automatisch hinzufügen, wenn Sie es nicht manuell eingeben möchten.
Dmitriy Popov

5

Ich benutze die finalganze Zeit für Objektattribute.

Das finalSchlüsselwort hat eine Sichtbarkeitssemantik, wenn es für Objektattribute verwendet wird. Grundsätzlich erfolgt das Festlegen des Werts eines endgültigen Objektattributs, bevor der Konstruktor zurückkehrt. Dies bedeutet, dass Sie die thisReferenz nicht aus dem Konstruktor entkommen lassen und finalfür alle verwenden Ihr Objekt (unter Java 5-Semantik) garantiert ist, dass es ordnungsgemäß erstellt wird, Ihre Attribute verwenden. Da es auch unveränderlich ist, kann es sicher veröffentlicht werden zu anderen Threads.

Bei unveränderlichen Objekten geht es nicht nur um Fadensicherheit. Sie machen es auch viel einfacher zu Grunde , über die Zustandsübergänge in Ihrem Programm, weil der Raum von dem, was kann ändern ist bewusst , und wenn konsequent genutzt, gründlich beschränkt auf nur die Dinge , die sollten geändert werden .

Ich mache manchmal auch Methoden endgültig, aber nicht so oft. Ich mache selten Klassen endgültig. Ich mache das im Allgemeinen, weil ich wenig brauche. Ich benutze Vererbung im Allgemeinen nicht viel. Ich bevorzuge stattdessen die Verwendung von Schnittstellen und Objektkompositionen - dies eignet sich auch für ein Design, das meiner Meinung nach oft einfacher zu testen ist. Wenn Sie anstelle konkreter Klassen auf Schnittstellen codieren, brauchen Sie das nicht , um die Verwendung Vererbung , wenn Sie testen, wie es ist, mit Frameworks wie JMock, viel einfacher zu Mock-Objekte mit Schnittstellen zu schaffen , als es mit konkreten Klassen ist.

Ich denke, ich sollte den Großteil meiner Klassen endgültig machen, aber ich bin noch nicht in den Habbit gekommen.


4

Ich muss viel Code für meinen Job lesen. Das Fehlen endgültiger Instanzvariablen ist eines der wichtigsten Dinge, die mich nerven und das Verständnis des Codes unnötig erschweren. Für mein Geld verursacht die endgültige Festlegung lokaler Variablen mehr Unordnung als Klarheit. Die Sprache sollte so gestaltet sein, dass dies die Standardeinstellung ist, aber wir müssen mit dem Fehler leben. Manchmal ist es nützlich, insbesondere bei Schleifen und bestimmten Zuweisungen mit einem If-else-Baum, aber meistens zeigt es an, dass Ihre Methode zu kompliziert ist.


Warum nicht ein Werkzeug verwenden, das die Unordnung reduziert?
Pacerier

@Pacerier Wie in einem Editor, der den Code falsch darstellt?
Tom Hawtin - Tackline

3

final sollte natürlich für Konstanten und zur Durchsetzung der Unveränderlichkeit verwendet werden, aber es gibt noch eine andere wichtige Verwendung für Methoden.

Effektives Java enthält einen ganzen Punkt (Punkt 15), der auf die Fallstricke einer unbeabsichtigten Vererbung hinweist. Wenn Sie Ihre Klasse nicht für die Vererbung entworfen und dokumentiert haben, kann das Erben von ihr zu unerwarteten Problemen führen (das Element gibt ein gutes Beispiel). Die Empfehlung lautet daher, dass Sie final für jede Klasse und / oder Methode verwenden, von der nicht geerbt werden sollte.

Das mag drakonisch erscheinen, macht aber Sinn. Wenn Sie eine Klassenbibliothek zur Verwendung durch andere schreiben, möchten Sie nicht, dass sie von Dingen erben, die nicht dafür entwickelt wurden. Sie werden sich aus Gründen der Rückenkompatibilität an eine bestimmte Implementierung der Klasse binden. Wenn Sie in einem Team programmieren, hindert nichts ein anderes Mitglied des Teams daran, das Finale zu entfernen, wenn es wirklich muss. Das Schlüsselwort lässt sie jedoch darüber nachdenken, was sie tun, und warnt sie, dass die Klasse, von der sie erben, nicht dafür ausgelegt ist. Daher sollten sie besonders vorsichtig sein.


3

Eine weitere Einschränkung ist, dass viele Leute final verwechseln, um zu bedeuten, dass sich der Inhalt der Instanzvariablen nicht ändern kann, anstatt dass sich die Referenz nicht ändern kann.


Und dieser Beitrag ist ein großer Beweis dafür.
InigoD

2

Selbst für lokale Variablen bedeutet das Wissen, dass es als endgültig deklariert ist, dass ich mir keine Sorgen machen muss, dass die Referenz später geändert wird. Dies bedeutet, dass ich beim Debuggen und wenn ich diese Variable später sehe, sicher bin, dass sie sich auf dasselbe Objekt bezieht. Das ist eine Sache weniger, über die ich mir Sorgen machen muss, wenn ich nach einem Fehler suche. Ein Bonus ist, dass wenn 99% der Variablen als endgültig deklariert werden, die wenigen Variablen, die wirklich variabel sind, besser hervorstechen. Außerdem kann der Compiler im Finale weitere mögliche dumme Fehler finden, die sonst möglicherweise unbemerkt bleiben.


2

Die Wahl, finalfür jeden Parameter in jeder Methode zu tippen , wird sowohl für Codierer als auch für Codeleser so irritierend sein.

Sobald die Irritation über den vernünftigen Wert hinausgeht, wechseln Sie zu Scala, wo die Argumente standardmäßig endgültig sind.

Sie können auch jederzeit Code-Styling-Tools verwenden, die dies automatisch für Sie erledigen. Alle IDEs haben sie implementiert oder als Plugins.


1

Final bei Verwendung mit Variablen in Java bietet einen Ersatz für Konstanten in C ++. Wenn also final und static für eine Variable verwendet wird, wird sie unveränderlich. Gleichzeitig macht migrierte C ++ - Programmierer ziemlich glücklich ;-)

Bei Verwendung mit Referenzvariablen können Sie das Objekt nicht erneut referenzieren, obwohl das Objekt bearbeitet werden kann.

Wenn final mit einer Methode verwendet wird, kann die Methode nicht von den Unterklassen überschrieben werden.

Sobald die Verwendung sehr klar ist, sollte sie mit Vorsicht verwendet werden. Dies hängt hauptsächlich vom Design ab, da die Verwendung von final auf der Methode den Polymorphismus nicht unterstützen würde.

Man sollte es nur für Variablen verwenden, wenn man verdammt sicher ist, dass der Wert der Variablen niemals geändert wird / werden sollte. Stellen Sie außerdem sicher, dass Sie die von SUN empfohlene Codierungskonvention befolgen, z. B.: Final int COLOR_RED = 1; (Großbuchstaben durch Unterstrich getrennt)

Verwenden Sie eine Referenzvariable nur, wenn Sie eine unveränderliche Referenz auf ein bestimmtes Objekt benötigen.

In Bezug auf den Lesbarkeitsteil ist zu beachten, dass Kommentare bei der Verwendung des endgültigen Modifikators eine sehr wichtige Rolle spielen.


Kann mir jemand sagen, warum dies abgelehnt wurde ??? Nur neugierig ..
Allmächtig

Es ist wahrscheinlich, weil Sie angeben, dass Sie es NUR bei XYZ endgültig machen sollten. Andere halten es für besser, ALLES endgültig zu machen, sofern dies nicht anders erforderlich ist.
Outlaw Programmer

1
Es ist überhaupt kein Ersatz für das Schlüsselwort C ++ const. -1.
tmj

1

Ich benutze sie nie für lokale Variablen, es gibt wenig Sinn für die zusätzliche Ausführlichkeit. Selbst wenn Sie nicht der Meinung sind, dass die Variable neu zugewiesen werden sollte, hat dies für die nächste Person, die den Code ändert, der anders denkt, kaum einen Unterschied. Da der Code geändert wird, ist möglicherweise der ursprüngliche Zweck, ihn endgültig zu machen, möglicherweise nicht mehr gültig. Wenn es nur um Klarheit geht, glaube ich, dass es an den negativen Auswirkungen der Ausführlichkeit scheitert.

Ähnliches gilt auch für Mitgliedsvariablen, da sie mit Ausnahme von Konstanten nur einen geringen Nutzen bringen.

Es hat auch keinen Einfluss auf die Unveränderlichkeit, da der beste Indikator dafür, dass etwas unveränderlich ist, darin besteht, dass es als solches dokumentiert ist und / oder keine Methoden hat, die das Objekt verändern können (dies ist zusammen mit dem Abschluss der Klasse der einzige Weg, dies zu gewährleisten es ist unveränderlich).

Aber hey, das ist nur meine Meinung :-)


1

Ich habe Eclipse so eingerichtet, dass alle Felder und Attribute, die nicht geändert werden, endgültig hinzugefügt werden. Dies funktioniert hervorragend mit den Eclipse-Aktionen "Speichern", mit denen diese endgültigen Modifikatoren (unter anderem) beim Speichern der Datei hinzugefügt werden.

Sehr empfehlenswert.

Schauen Sie sich meinen Blog-Beitrag von Eclipse Save Actions an.


1

Für Argumente denke ich, dass sie nicht benötigt werden. Meistens verletzten sie nur die Lesbarkeit. Das Neuzuweisen einer Argumentvariablen ist so wahnsinnig dumm, dass ich ziemlich sicher sein sollte, dass sie sowieso als Konstanten behandelt werden können.

Die Tatsache, dass Eclipse das endgültige Rot färbt, erleichtert das Erkennen von Variablendeklarationen im Code, was meiner Meinung nach die Lesbarkeit meistens verbessert.

Ich versuche, die Regel durchzusetzen, dass alle Variablen endgültig sein sollten, es gibt keinen extrem gültigen Grund, dies nicht zu tun. Es ist so viel einfacher, die Frage "Was ist diese Variable?" Zu beantworten. Frage, ob du nur die Initilierung finden und sicher sein musst, dass es das ist.

Ich werde heutzutage ziemlich nervös wegen nicht endgültiger Variablen. Es ist wie der Unterschied, ob ein Messer in einem Faden über Ihrem Kopf hängt oder nur eine Küchenschublade ...

Eine letzte Variable ist nur ein guter Weg, um Werte zu beschriften.

Eine nicht endgültige Variable ist an einen Teil eines fehleranfälligen Algorithmus gebunden.

Eine nette Funktion ist, dass, wenn die Option, eine Variable für einen Algorithmus nicht in Frage zu stellen, die meiste Zeit darin besteht, stattdessen eine Methode zu schreiben, die normalerweise den Code erheblich verbessert.


1

Ich programmiere jetzt schon eine Weile und benutze final, wann immer ich kann. Nachdem ich dies eine Weile getan habe (für Variablen, Methodenparameter und Klassenattribute), kann ich sagen, dass 90% (oder mehr) meiner Variablen tatsächlich endgültig sind. Ich denke, der Vorteil, dass Variablen NICHT geändert werden, wenn Sie dies nicht möchten (ich habe das schon einmal gesehen und es ist manchmal schmerzhaft), zahlt sich für die zusätzliche Eingabe und die zusätzlichen "endgültigen" Schlüsselwörter in Ihrem Code aus.

Wenn ich jedoch eine Sprache entwerfen würde, würde ich jede Variable endgültig machen, sofern sie nicht durch ein anderes Schlüsselwort geändert wird.

Ich benutze final nicht oft für Klassen und Methoden, dachte ich. Dies ist eine mehr oder weniger komplizierte Entwurfsauswahl, es sei denn, Ihre Klasse ist eine Utility-Klasse (in diesem Fall sollten Sie nur einen privaten Konstruktor haben).

Ich benutze auch Collections.unmodizable ..., um bei Bedarf nicht modifizierbare Listen zu erstellen.


0

Die Verwendung anonymer lokaler Klassen für Ereignis-Listener und dergleichen ist in Java ein gängiges Muster. Das häufigste Schlüsselwort wird verwendet, um sicherzustellen, dass Variablen im Gültigkeitsbereich für den geraden Listener zugänglich sind.

Wenn Sie jedoch feststellen, dass Sie viele endgültige Anweisungen in Ihren Code einfügen müssen. Das könnte ein guter Hinweis sein, dass Sie etwas falsch machen.

Der oben veröffentlichte Artikel enthält dieses Beispiel:

public void doSomething(int i, int j) {
    final int n = i + j; // must be declared final

    Comparator comp = new Comparator() {
        public int compare(Object left, Object right) {
            return n; // return copy of a local variable
        }
    };
}

0

Ich benutze es für Konstanten innerhalb und außerhalb von Methoden.

Ich benutze es nur manchmal für Methoden, weil ich nicht weiß, ob eine Unterklasse eine bestimmte Methode NICHT überschreiben möchte (aus welchen Gründen auch immer).

In Bezug auf Klassen habe ich nur für einige Infrastrukturklassen die Abschlussklasse verwendet.

IntelliJ IDEA warnt Sie, wenn ein Funktionsparameter in eine Funktion geschrieben wird. Daher habe ich die Verwendung von final für Funktionsargumente eingestellt. Ich sehe sie auch nicht in der Java Runtime-Bibliothek.


0

Ich verwende final kaum für Methoden oder Klassen, weil ich es gerne zulasse, dass Leute sie überschreiben.

Ansonsten benutze ich endlich nur wenn es ein ist public/private static final type SOME_CONSTANT;


Hmm..bearbeitet an einer Stelle..wenn noch endlich in der zweiten Zeile steht ;-)
Allmächtig

Menschen zu erlauben, Werte zu überschreiben, ist die einzige Quelle für Überraschungen und schwer herauszufindende Fehler
RAY

0

Das Markieren des Klassenfinales kann auch dazu führen, dass einige Methodenbindungen zur Kompilierungszeit statt zur Laufzeit ausgeführt werden. Betrachten Sie unten "v2.foo ()" - der Compiler weiß, dass B keine Unterklasse haben kann, daher kann foo () nicht überschrieben werden, sodass die aufzurufende Implementierung zur Kompilierungszeit bekannt ist. Wenn Klasse B NICHT als endgültig markiert ist, ist es möglich, dass der tatsächliche Typ von v2 eine Klasse ist, die B erweitert und foo () überschreibt.

class A {
    void foo() {
        //do something
    }
}
final class B extends A {
    void foo() {
    }
}
class Test {
    public void t(A v1, B v2) {
        v1.foo();
        v2.foo();
    }
}

-1

Die Verwendung von final für Konstanten wird dringend empfohlen. Ich würde es jedoch nicht für Methoden oder Klassen verwenden (oder zumindest eine Weile darüber nachdenken), da es das Testen schwieriger, wenn nicht unmöglich macht. Wenn Sie unbedingt eine Klasse oder Methode endgültig machen müssen, stellen Sie sicher, dass diese Klasse eine Schnittstelle implementiert, damit Sie einen Mock haben können , der dieselbe Schnittstelle implementiert.


Das Testen wird dadurch nicht schwieriger, da Sie ohnehin Schnittstellen verwenden sollten.
Chris Vest
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.