Java-Methodenargumente als endgültig festlegen

Lesezeit: 7 Minuten

Benutzer-Avatar
John

Was für ein Unterschied final macht zwischen dem Code unten. Gibt es einen Vorteil, die Argumente als zu deklarieren? final.

public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){  
    return ....
}

public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
        final Timezone toTz){
    return ....
}

  • Es gibt Codeanalysatoren, die warnen, wenn ein Parameter wiederverwendet oder neu zugewiesen wird. (Gleiches gilt für lokale Variablen) IMHO, Dies ist ein besserer Weg, um solche Parameter abzufangen, wenn Sie der Meinung sind, dass das Ändern unerwünscht ist.

    – Peter Lawrey

    12. November 2010 um 8:54 Uhr

  • Mögliches Duplikat von Warum sollte ich das Schlüsselwort “final” für einen Methodenparameter in Java verwenden?

    – james.garriss

    10. Oktober 2017 um 18:37 Uhr

  • Ich bin der Meinung, dass Java standardmäßig alle Eingabemethodenargumente als endgültig festlegen sollte. Und wenn ich dann die Referenz ändern möchte, müsste ich es manuell tun. Auf diese Weise würde der Schuldfaktor viele solcher Fälle verhindern.

    – Sid

    16. September 2018 um 5:15 Uhr

Benutzer-Avatar
PeterMmm

Da ein formaler Methodenparameter eine lokale Variable ist, können Sie von inneren anonymen Klassen nur darauf zugreifen, wenn sie als final deklariert sind.

Dies erspart Ihnen die Deklaration einer weiteren lokalen finalen Variablen im Methodenrumpf:

 void m(final int param) {
        new Thread(new Runnable() {
            public void run() {
                System.err.println(param);
            }
        }).start();
    }

  • +1: Dies ist ein wichtiger Anwendungsfall und das einzige Mal, wenn Sie brauchen es. (Den Rest der Zeit geht es nur darum, was praktisch ist, um dem Programmierer zu helfen.)

    – Donal Fellows

    12. November 2010 um 9:22 Uhr

  • Darf ich nach der Begründung fragen?

    – KodeWarrior

    18. Januar 2014 um 15:42 Uhr

  • Mit Java 8 nicht mehr nötig.

    – Amit Parashar

    5. November 2015 um 7:57 Uhr

  • @simgineer hier lesen: stackoverflow.com/questions/28408109/…

    – PeterMmm

    17. Februar 2018 um 8:54 Uhr

  • @AmitParashar Stimmt, aber Java 8 ist es Sie ersparen sich nur die Verwendung des Schlüsselworts “final” jedes Mal, wenn Sie die Variable in einer inneren Klasse verwenden müssen … In Wirklichkeit macht der Compiler lediglich die Endgültigkeit implizit, Sie müssen immer noch die Variable sein effektiv final … Sie erhalten also immer noch einen Kompilierzeitfehler, falls Sie später versuchen, ihn zuzuweisen! Java 8: SCHLEIFEN 100 🙂

    – Varun

    9. April 2019 um 18:33 Uhr

Benutzer-Avatar
pgras

Auszug aus Das letzte Wort zum letzten Schlüsselwort

Endgültige Parameter

Das folgende Beispiel deklariert endgültige Parameter:

public void doSomething(final int i, final int j)
{
  // cannot change the value of i or j here...
  // any change would be visible only inside the method...
}

final wird hier verwendet, um sicherzustellen, dass die beiden Indizes i und j nicht versehentlich von der Methode zurückgesetzt werden. Dies ist eine praktische Möglichkeit, sich vor einem heimtückischen Fehler zu schützen, der fälschlicherweise den Wert Ihrer Parameter ändert. Im Allgemeinen sind kurze Methoden ein besserer Weg, um sich vor dieser Art von Fehlern zu schützen, aber letzte Parameter können eine nützliche Ergänzung zu Ihrem Codierungsstil sein.

Beachten Sie, dass abschließende Parameter nicht als Teil der Methodensignatur betrachtet werden und vom Compiler beim Auflösen von Methodenaufrufen ignoriert werden. Parameter können als final (oder nicht) deklariert werden, ohne Einfluss darauf, wie die Methode überschrieben wird.

  • Es ist möglicherweise besser, für dieses Beispiel Objekte anstelle von Primitiven zu verwenden, da Änderungen an Primitiven immer nur innerhalb der Methode sichtbar sind. Und im Fall von Objekten können Sie sie immer noch ändern. Sie können einfach nicht auf ein neues Objekt zeigen. Tatsächlich, jetzt denke ich darüber nach, ändert final nicht wirklich etwas im Vergleich zum Weglassen, außer dass eine Variablendeklaration mit AICs gespeichert wird und der Compiler auf versehentliche Änderungen von Parametern hinweist, die Sie aus irgendeinem Grund nicht ändern wollten .

    – Rob Grant

    15. August 2014 um 9:58 Uhr

Benutzer-Avatar
djna

Das Finale verhindert, dass Sie der Variablen einen neuen Wert zuweisen, und dies kann hilfreich sein, um Tippfehler abzufangen. Stilistisch möchten Sie vielleicht die empfangenen Parameter unverändert lassen und nur lokalen Variablen zuweisen, also würde final helfen, diesen Stil durchzusetzen.

Ich muss zugeben, dass ich selten daran denke, final für Parameter zu verwenden, vielleicht sollte ich das tun.

public int example(final int basicRate){
    int discountRate;

    discountRate = basicRate - 10;
    // ... lots of code here 
    if ( isGoldCustomer ) {
        basicRate--;  // typo, we intended to say discountRate--, final catches this
    }
    // ... more code here

    return discountRate;
}

  • Tolles Beispiel dafür, wie es nützlich sein kann, Argumente als endgültig zu deklarieren. Ich bin parteiisch dafür, aber sie sind auch ein Schluck für 3+ Parameter.

    – JoseHdez_2

    21. Dezember 2018 um 10:54 Uhr

Es macht keinen großen Unterschied. Es bedeutet nur, dass Sie nicht schreiben können:

stamp = null;
fTz = new ...;

aber du kannst trotzdem schreiben:

stamp.setXXX(...);
fTz.setXXX(...);

Es ist hauptsächlich ein Hinweis für den Wartungsprogrammierer, der Ihnen folgt, dass Sie dem Parameter keinen neuen Wert irgendwo in der Mitte Ihrer Methode zuweisen werden, wo es nicht offensichtlich ist und daher Verwirrung stiften könnte.

Das Schlüsselwort final, wenn es für Parameter/Variablen in Java verwendet wird, markiert die Referenz als final. Beim Übergeben eines Objekts an eine andere Methode erstellt das System eine Kopie der Referenzvariablen und übergibt sie an die Methode. Indem Sie die neuen Referenzen final markieren, schützen Sie sie vor einer erneuten Zuordnung. Es wird manchmal als gute Codierungspraxis angesehen.

  • Ich muss etwas hinzufügen: Wenn Parameter primitiv sind, sehe ich keine Unterschiede. Außerdem, wenn Parameter Sammlungen sind (eine Liste von Objekten …), konnte das Hinzufügen von final nicht verhindern, dass sie geändert werden.

    – Sam003

    23. Juli 2015 um 0:08 Uhr


  • Unveränderlichkeit ist immer eine wünschenswerte Eigenschaft. Java hat es nicht von Haus aus. Das Finalisieren von Variablen stellt zumindest die Referenzintegrität sicher.

    – Sid

    23. Juli 2015 um 16:29 Uhr

  • Ich stimme zu. Aber wenn wir wirklich Unveränderlichkeit für Objekte erreichen wollen, könnten wir versuchen, einen tiefen Klon zu erstellen.

    – Sam003

    23. Juli 2015 um 17:21 Uhr

  • final hilft überhaupt nicht bei der Unveränderlichkeit. Die Änderungen an primitiven Werten gehen außerhalb des Methodenbereichs verloren, unabhängig davon, ob der Parameter als final markiert ist oder nicht. Änderungen an änderbaren Objekten werden außerhalb des Gültigkeitsbereichs weitergegeben, unabhängig davon, ob der Parameter als final markiert ist oder nicht. „Nutzlos“ ist das Wort, das mir in den Sinn kommt.

    – Augusti Sánchez

    29. Januar um 1:19 Uhr

  • Eine unveränderliche Referenz ist der erste Schritt zur Unveränderlichkeit.

    – Sid

    29. Januar um 6:28 Uhr

Benutzer-Avatar
dimitrisli

Für den Körper dieser Methode die final Schlüsselwort verhindert, dass die Argumentreferenzen versehentlich neu zugewiesen werden, was in diesen Fällen zu einem Kompilierungsfehler führt (die meisten IDEs werden sich sofort beschweren). Einige mögen argumentieren, dass die Verwendung final Im Allgemeinen wird dies, wann immer möglich, die Dinge beschleunigen, aber das ist bei neueren JVMs nicht der Fall.

  • Ich muss etwas hinzufügen: Wenn Parameter primitiv sind, sehe ich keine Unterschiede. Außerdem, wenn Parameter Sammlungen sind (eine Liste von Objekten …), konnte das Hinzufügen von final nicht verhindern, dass sie geändert werden.

    – Sam003

    23. Juli 2015 um 0:08 Uhr


  • Unveränderlichkeit ist immer eine wünschenswerte Eigenschaft. Java hat es nicht von Haus aus. Das Finalisieren von Variablen stellt zumindest die Referenzintegrität sicher.

    – Sid

    23. Juli 2015 um 16:29 Uhr

  • Ich stimme zu. Aber wenn wir wirklich Unveränderlichkeit für Objekte erreichen wollen, könnten wir versuchen, einen tiefen Klon zu erstellen.

    – Sam003

    23. Juli 2015 um 17:21 Uhr

  • final hilft überhaupt nicht bei der Unveränderlichkeit. Die Änderungen an primitiven Werten gehen außerhalb des Methodenbereichs verloren, unabhängig davon, ob der Parameter als final markiert ist oder nicht. Änderungen an änderbaren Objekten werden außerhalb des Gültigkeitsbereichs weitergegeben, unabhängig davon, ob der Parameter als final markiert ist oder nicht. „Nutzlos“ ist das Wort, das mir in den Sinn kommt.

    – Augusti Sánchez

    29. Januar um 1:19 Uhr

  • Eine unveränderliche Referenz ist der erste Schritt zur Unveränderlichkeit.

    – Sid

    29. Januar um 6:28 Uhr

Benutzer-Avatar
Gemeinschaft

Zwei Vorteile, die ich sehe, sind aufgelistet:

1 Das Markieren des Methodenarguments als final verhindert die Neuzuweisung des Arguments innerhalb der Methode

Aus deinem Beispiel

    public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
            final Timezone toTz){
    
    // THIS WILL CAUSE COMPILATION ERROR as fTz is marked as final argument

      fTz = Calendar.getInstance().getTimeZone();     
      return ..
    
    }

In einer komplizierten Methode hilft das Markieren der Argumente als endgültig bei der versehentlichen Interpretation dieser Argumente als lokale Methodenvariablen, und eine Neuzuweisung als Compiler wird diese Fälle wie im Beispiel gezeigt kennzeichnen.

2 Übergabe des Arguments an eine anonyme innere Klasse

Da ein formaler Methodenparameter eine lokale Variable ist, können Sie von inneren anonymen Klassen nur darauf zugreifen, wenn sie als final deklariert sind.

1306590cookie-checkJava-Methodenargumente als endgültig festlegen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy