Stoppen Sie die Neuzuweisung einer Variablen
Obwohl diese Antworten intellektuell interessant sind, habe ich die kurze einfache Antwort nicht gelesen:
Verwenden Sie das Schlüsselwort final, wenn der Compiler verhindern soll, dass eine Variable einem anderen Objekt neu zugewiesen wird.
Unabhängig davon, ob es sich bei der Variablen um eine statische Variable, eine Mitgliedsvariable, eine lokale Variable oder eine Argument- / Parametervariable handelt, ist der Effekt völlig gleich.
Beispiel
Lassen Sie uns den Effekt in Aktion sehen.
Betrachten Sie diese einfache Methode, bei der den beiden Variablen ( arg und x ) unterschiedliche Objekte zugewiesen werden können.
// Example use of this method:
// this.doSomething( "tiger" );
void doSomething( String arg ) {
String x = arg; // Both variables now point to the same String object.
x = "elephant"; // This variable now points to a different String object.
arg = "giraffe"; // Ditto. Now neither variable points to the original passed String.
}
Markieren Sie die lokale Variable als final . Dies führt zu einem Compilerfehler.
void doSomething( String arg ) {
final String x = arg; // Mark variable as 'final'.
x = "elephant"; // Compiler error: The final local variable x cannot be assigned.
arg = "giraffe";
}
Markieren wir stattdessen die Parametervariable als final . Auch dies führt zu einem Compilerfehler.
void doSomething( final String arg ) { // Mark argument as 'final'.
String x = arg;
x = "elephant";
arg = "giraffe"; // Compiler error: The passed argument variable arg cannot be re-assigned to another object.
}
Moral der Geschichte:
Wenn Sie sicherstellen möchten, dass eine Variable immer auf dasselbe Objekt zeigt, markieren Sie die Variable final .
Argumente niemals neu zuweisen
Als gute Programmierpraxis (in jeder Sprache) sollten Sie einem anderen Objekt als dem von der aufrufenden Methode übergebenen Objekt niemals eine Parameter- / Argumentvariable neu zuweisen. In den obigen Beispielen sollte man niemals die Zeile schreiben arg =
. Da Menschen Fehler machen und Programmierer Menschen sind, bitten wir den Compiler, uns zu unterstützen. Markieren Sie jede Parameter- / Argumentvariable als 'final', damit der Compiler solche Neuzuweisungen finden und kennzeichnen kann.
Im Rückblick
Wie in anderen Antworten erwähnt ... Angesichts des ursprünglichen Entwurfsziels von Java, Programmierern dabei zu helfen, dumme Fehler wie das Lesen über das Ende eines Arrays hinaus zu vermeiden, sollte Java so konzipiert sein, dass alle Parameter- / Argumentvariablen automatisch als "endgültig" erzwungen werden. Mit anderen Worten, Argumente sollten keine Variablen sein . Aber im Nachhinein ist 20/20 Vision, und die Java-Designer hatten zu dieser Zeit alle Hände voll zu tun.
Also immer final
zu allen Argumenten hinzufügen ?
Sollten wir final
zu jedem deklarierten Methodenparameter hinzufügen ?
- Theoretisch ja.
- In der Praxis nein.
➥ final
Nur hinzufügen, wenn der Code der Methode lang oder kompliziert ist und das Argument möglicherweise mit einer lokalen oder Mitgliedsvariablen verwechselt und möglicherweise neu zugewiesen wird.
Wenn Sie sich für die Praxis entscheiden, niemals ein Argument neu zuzuweisen, neigen Sie dazu final
, jedem ein Argument hinzuzufügen . Dies ist jedoch langwierig und erschwert das Lesen der Erklärung.
Für kurzen einfachen Code, bei dem das Argument offensichtlich ein Argument ist und weder eine lokale Variable noch eine Mitgliedsvariable, mache ich mir nicht die Mühe, das hinzuzufügen final
. Wenn der Code ganz offensichtlich ist und keine Chance besteht, dass ich oder ein anderer Programmierer versehentlich die Argumentvariable als etwas anderes als ein Argument verwechselt oder umgestaltet, dann stören Sie sich nicht. In meiner eigenen Arbeit füge ich final
nur längeren oder komplexeren Code hinzu, bei dem ein Argument möglicherweise mit einer lokalen oder Mitgliedsvariablen verwechselt wird.
Ein weiterer Fall wurde der Vollständigkeit halber hinzugefügt
public class MyClass {
private int x;
//getters and setters
}
void doSomething( final MyClass arg ) { // Mark argument as 'final'.
arg = new MyClass(); // Compiler error: The passed argument variable arg cannot be re-assigned to another object.
arg.setX(20); // allowed
// We can re-assign properties of argument which is marked as final
}