459 Stimmen

Warum sollte ich das Schlüsselwort "final" für einen Methodenparameter in Java verwenden?

Ich kann nicht verstehen, wo die final Schlüsselwort ist wirklich praktisch, wenn es für Methodenparameter verwendet wird.

Wenn wir die Verwendung anonymer Klassen, die Lesbarkeit und die Absichtserklärung ausklammern, scheint es mir fast wertlos zu sein.

Zu erzwingen, dass einige Daten konstant bleiben, ist nicht so einfach, wie es scheint.

  • Handelt es sich bei dem Parameter um ein Primitivum, hat dies keine Auswirkungen, da der Parameter als Wert an die Methode übergeben wird und seine Änderung keine Auswirkungen außerhalb des Anwendungsbereichs hat.

  • Wenn wir einen Parameter per Verweis übergeben, dann ist der Verweis selbst eine lokale Variable, und wenn der Verweis innerhalb der Methode geändert wird, hat das keine Auswirkungen außerhalb des Methodenbereichs.

Betrachten Sie das folgende einfache Testbeispiel. Dieser Test ist erfolgreich, obwohl die Methode den Wert des ihr übergebenen Verweises geändert hat, er hat also keine Auswirkungen.

public void testNullify() {
    Collection<Integer> c  = new ArrayList<Integer>();      
    nullify(c);
    assertNotNull(c);       
    final Collection<Integer> c1 = c;
    assertTrue(c1.equals(c));
    change(c);
    assertTrue(c1.equals(c));
}

private void change(Collection<Integer> c) {
    c = new ArrayList<Integer>();
}

public void nullify(Collection<?> t) {
    t = null;
}

20voto

Germán Punkte 4405

Die Verwendung von final in einem Methodenparameter hat nichts damit zu tun, was mit dem Argument auf der Seite des Aufrufers geschieht. Es soll nur kennzeichnen, dass es sich innerhalb der Methode nicht ändert. Da ich versuche, einen funktionaleren Programmierstil anzunehmen, sehe ich irgendwie den Wert darin.

11voto

starblue Punkte 53167

Ich persönlich verwende final nicht bei Methodenparametern, weil es zu viel Unordnung in die Parameterlisten bringt. Ich ziehe es vor, durch etwas wie Checkstyle zu erzwingen, dass Methodenparameter nicht geändert werden.

Für lokale Variablen verwende ich, wann immer es möglich ist, final. Ich lasse Eclipse das sogar automatisch in meinem Setup für persönliche Projekte tun.

Ich würde mir auf jeden Fall etwas Stärkeres wie C/C++ const wünschen.

4voto

Lawrence Punkte 1007

Da Java Kopien von Argumenten weitergibt, halte ich die Relevanz von final ist eher begrenzt. Ich vermute, dass die Gewohnheit aus der C++-Ära stammt, in der man verhindern konnte, dass Referenzinhalte geändert werden, indem man eine const char const * . Ich habe das Gefühl, dass solche Dinge den Eindruck erwecken, dass der Entwickler von Natur aus dumm ist und vor wirklich jedem Zeichen, das er eingibt, geschützt werden muss. In aller Bescheidenheit möchte ich sagen, dass ich nur sehr wenige Bugs schreibe, auch wenn ich sie auslasse. final (es sei denn, ich möchte nicht, dass jemand meine Methoden und Klassen außer Kraft setzt). Vielleicht bin ich einfach ein Entwickler der alten Schule.

4voto

Darrell Teague Punkte 3794

Kurze Antwort: final hilft ein klein wenig, aber... verwenden Sie stattdessen defensive Programmierung auf der Client-Seite.

In der Tat, das Problem mit final ist, dass sie nur die Referenz ist unverändert und erlaubt fröhlich, dass die referenzierten Objektmitglieder verändert werden, ohne dass der Aufrufer es merkt. Die beste Praxis in dieser Hinsicht ist daher eine defensive Programmierung auf der Seite des Aufrufers, die tief unveränderliche Instanzen oder tiefe Kopien von Objekten erstellt, die Gefahr laufen, von skrupellosen APIs ausgeraubt zu werden.

2voto

Chris Milburn Punkte 803

Ich verwende niemals "final" in einer Parameterliste, das bringt nur Unordnung ins Spiel, wie meine Vorredner bereits gesagt haben. Auch in Eclipse können Sie die Parameterzuweisung so einstellen, dass ein Fehler generiert wird, so dass die Verwendung von final in einer Parameterliste für mich ziemlich überflüssig erscheint. Interessanterweise, wenn ich die Eclipse-Einstellung für die Parameterzuweisung aktiviert einen Fehler auf sie gefangen diesen Code (dies ist nur, wie ich den Fluss erinnern, nicht den eigentlichen Code. ) :-

private String getString(String A, int i, String B, String C)
{
    if (i > 0)
        A += B;

    if (i > 100)
        A += C;

    return A;
}

Um den Teufel an die Wand zu malen: Was genau ist falsch an dieser Vorgehensweise?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X