web-dev-qa-db-de.com

endgültiges Schlüsselwort in Methodenparametern

Ich treffe oft Methoden, die wie folgt aussehen:

public void foo(final String a, final int[] b, final Object1 c){
}

Was passiert, wenn diese Methode aufgerufen wird, ohne die endgültigen Parameter zu übergeben. Das heißt, ein Objekt1, das später geändert wird (also nicht als endgültig deklariert ist), kann problemlos an diese Methode übergeben werden

124
Aly

Java erstellt immer eine Kopie der Parameter, bevor sie an Methoden gesendet werden. Das bedeutet, dass das Finale keinen Unterschied für den aufrufenden Code bedeutet. Dies bedeutet nur, dass die Variablen innerhalb der Methode nicht neu zugewiesen werden können. (Beachten Sie, dass Sie bei einem endgültigen Objekt immer noch die Attribute des Objekts ändern können.).

159
Thirler

Unter bestimmten Umständen sind Sie erforderlich , um sie als endgültig zu deklarieren - andernfalls führt dies zu Kompilierungsfehlern--, dh sie werden in anonyme Klassen durchgeleitet. Grundbeispiel:

public FileFilter createFileExtensionFilter(final String extension) {
    FileFilter fileFilter = new FileFilter() {
        public boolean accept(File pathname) {
            return pathname.getName().endsWith(extension);
        }
    };

    // What would happen when it's allowed to change extension here?
    // extension = "foo";

    return fileFilter;
}

Das Entfernen des Modifizierers final würde zu einem Kompilierfehler führen, da nicht mehr garantiert werden kann, dass der Wert eine Laufzeitkonstante ist. Eine Änderung des Werts außerhalb der anonymen Klasse würde nämlich dazu führen, dass sich die anonyme Klasseninstanz nach dem Erstellen anders verhält.

77
BalusC

Java ist nur Wertübergabe. (oder besser - Pass-Referenz nach Wert)

Das übergebene Argument und das Argument innerhalb der Methode sind also zwei verschiedene Handler, die auf dasselbe Objekt (Wert) zeigen. 

Wenn Sie also den Status des Objekts ändern, wird dies auf jede andere Variable reflektiert, auf die es verweist. Wenn Sie dem Argument jedoch ein neues Objekt (Wert) zuweisen, werden andere Variablen, die auf dieses Objekt (Wert) zeigen, nicht erneut zugewiesen.

51
Bozho

Das Schlüsselwort final in einem Methodenparameter bedeutet für den Aufrufer absolut nichts. Es bedeutet auch absolut nichts für das laufende Programm, da seine Anwesenheit oder Abwesenheit den Bytecode nicht verändert. Sie stellt nur sicher, dass der Compiler sich beschwert, wenn die Parametervariable innerhalb der Methode neu zugewiesen wird. Das ist alles. Aber das ist genug.

Einige Programmierer (wie ich) denken, dass dies eine sehr gute Sache ist, und verwenden final für fast jeden Parameter. Es macht das Verstehen einer langen oder komplexen Methode einfacher (obwohl man argumentieren könnte, dass lange und komplexe Methoden umgestaltet werden sollten.) Außerdem werden Methodenparameter beleuchtet, die nicht mit final markiert sind.

27

Betrachten Sie diese Implementierung von foo ():

public void foo(final String a) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.print(a);
        }
    }); 
}

Da die Runnable-Instanz die Methode überleben würde, würde dies ohne das final-Schlüsselwort nicht kompilieren. final teilt dem Compiler mit, dass es sicher ist, eine Kopie der Referenz zu verwenden (um später darauf zu verweisen). Somit ist es die Referenz , die als endgültig betrachtet wird, nicht der Wert . Mit anderen Worten: Als Anrufer können Sie nichts vermasseln ...

17
Rahel Lüthy

Wenn Sie einen Parameter als final deklarieren, können Sie den Wert nicht ändern.

class Bike11 {  
    int cube(final int n) {  
        n=n+2;//can't be changed as n is final  
        n*n*n;  
     }  
    public static void main(String args[]) {  
        Bike11 b=new Bike11();  
        b.cube(5);  
    }  
}   

Ausgabe: Fehler beim Kompilieren

Für weitere Informationen besuchen Sie bitte mein Blog: http://javabyroopam.blogspot.com

2
Roopam

final bedeutet, dass Sie den Wert dieser Variablen nicht mehr ändern können, sobald sie zugewiesen wurde.

In der Zwischenzeit bedeutet die Verwendung von final für die Argumente in diesen Methoden , dass der Programmierer während der Ausführung der Methode ..__ ihren Wert nicht ändern kann final Variablen können nicht neu zugewiesen werden.

1
SilentKnight

das letzte Schlüsselwort im Methodeneingabeparameter wird nicht benötigt. Java erstellt eine Kopie des Verweises auf das Objekt, sodass das Objekt nicht finalisiert wird, sondern nur der Verweis, der keinen Sinn macht

0
ttati

@stuXnet, ich könnte das genaue Gegenteil machen. Wenn Sie ein Objekt an eine Funktion übergeben und die Eigenschaften des übergebenen Objekts ändern, wird der Aufrufer der Funktion den geänderten Wert in seiner Variablen sehen. Dies bedeutet, dass das Bezugssystem durchlaufen wird, nicht der Wert.

Verwirrend ist die Definition von Pass by Value oder Pass by Reference in einem System, in dem die Verwendung von Zeigern für den Endbenutzer vollständig verborgen ist. 

Java ist definitiv NICHT über den Wert übergeben, da dies bedeutet, dass man das übergebene Objekt mutieren könnte und das Original nicht betroffen wäre. 

Beachten Sie, dass Sie keine Grundelemente mutieren können, sondern nur Variablen zuweisen können. Daher ist das Testen einer Referenzübergabe oder eines Werts mithilfe von Primitiven kein Test. 

Was Sie in Java nicht tun können, was in anderen Sprachen möglich ist, besteht darin, die Variablen des Aufrufers einem neuen Wert zuzuweisen, da Java keine Zeiger enthält. Dies macht ihn verwirrend. 

0
Armand

Zeichenfolgen sind unveränderlich, daher können Sie die Zeichenfolge nachträglich nicht ändern (Sie können nur die Variable, die das Zeichenkettenobjekt enthielt, auf ein anderes Zeichenkettenobjekt verweisen lassen).

Dies ist jedoch nicht der Grund, warum Sie eine beliebige Variable an einen final-Parameter binden können. Der Compiler prüft lediglich, dass der Parameter in der Methode nicht neu zugewiesen wird. Dies ist gut für Dokumentationszwecke, möglicherweise für einen guten Stil, und kann sogar dazu beitragen, den Bytecode für die Geschwindigkeit zu optimieren (obwohl dies in der Praxis nicht viel zu tun scheint). 

Aber auch wenn Sie einen Parameter innerhalb einer Methode neu zuweisen, bemerkt der Aufrufer dies nicht, da Java alle Parameter nach Wert übergibt. Nach der Sequenz

  a = someObject();
  process(a);

die Felder von a mögen sich geändert haben, aber a ist immer noch das gleiche Objekt, das es zuvor war. In Pass-by-Reference-Sprachen trifft dies möglicherweise nicht zu.

0
Kilian Foth