Java 方法参数中的final关键字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2236599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
final keyword in method parameters
提问by Aly
I often encounter methods which look like the following:
我经常遇到如下所示的方法:
public void foo(final String a, final int[] b, final Object1 c){
}
What happens if this method is called without passing it final parameters. i.e. an Object1 that is later changed (so is not declared as final) can be passed to this method just fine
如果在没有传递最终参数的情况下调用此方法会发生什么。即稍后更改的 Object1(因此未声明为 final)可以很好地传递给此方法
采纳答案by Thirler
Java always makes a copy of parameters before sending them to methods. This means the final doesn't mean any difference for the calling code. This only means that inside the method the variables can not be reassigned. (note that if you have a final object, you can still change the attributes of the object).
Java 总是在将参数发送到方法之前制作参数的副本。这意味着 final 对调用代码没有任何区别。这仅意味着在方法内部不能重新分配变量。(请注意,如果您有最终对象,您仍然可以更改该对象的属性)。
回答by Bozho
Java is only pass-by-value. (or better - pass-reference-by-value)
Java 只是按值传递。(或更好 - 按值传递引用)
So the passed argument and the argument within the method are two differenthandlers pointing to the same object (value).
所以传入的参数和方法内的参数是指向同一个对象(值)的两个不同的处理程序。
Therefore if you change the stateof the object, it is reflected to every other variable that's referencing it. But if you re-assign a new object (value) to the argument, then other variables pointing to this object (value) do not get re-assigned.
因此,如果您更改对象的状态,它会反映到引用它的所有其他变量。但是,如果您将新对象(值)重新分配给参数,则不会重新分配指向该对象(值)的其他变量。
回答by Rahel Lüthy
Consider this implementation of foo():
考虑 foo() 的这个实现:
public void foo(final String a) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.print(a);
}
});
}
Because the Runnable
instance would outlive the method, this wouldn't compile without the final
keyword -- final
tells the compiler that it's safe to take a copy of the reference (to refer to it later). Thus, it's the referencethat's considered final, not the value. In other words: As a caller, you can't mess anything up...
因为Runnable
实例的生命周期比方法长,所以如果没有final
关键字,这将无法编译——final
告诉编译器获取引用的副本是安全的(稍后参考)。因此,它是被认为是最终的引用,而不是值。换句话说:作为来电者,您不能搞砸任何事情......
回答by Kilian Foth
Strings are immutable, so actully you can't change the String afterwards (you can only make the variable that held the String object point to a different String object).
字符串是不可变的,因此实际上您之后无法更改字符串(您只能使保存 String 对象的变量指向不同的 String 对象)。
However, that is not the reason why you can bind any variable to a final
parameter. All the compiler checks is that the parameter is not reassigned withinthe method. This is good for documentation purposes, arguably good style, and may even help optimize the byte code for speed (although this seems not to do very much in practice).
但是,这不是您可以将任何变量绑定到final
参数的原因。所有的编译器检查的是,该参数不重新分配中的方法。这有利于文档目的,可以说是很好的风格,甚至可能有助于优化字节码以提高速度(尽管这在实践中似乎没有太大作用)。
But even if you do reassign a parameter within a method, the caller doesn't notice that, because java does all parameter passing by value. After the sequence
但是即使您在方法中重新分配了一个参数,调用者也不会注意到这一点,因为 java 会按值传递所有参数。序列后
a = someObject();
process(a);
the fields of a may have changed, but a is still the same object it was before. In pass-by-reference languages this may not be true.
a 的字段可能已更改,但 a 仍然是以前的对象。在传递引用语言中,这可能不是真的。
回答by BalusC
There is a circumstance where you're requiredto declare it final --otherwise it will result in compile error--, namely passing them through into anonymous classes. Basic example:
在某些情况下,您需要将其声明为 final —— 否则会导致编译错误 —— 即将它们传递到匿名类中。基本示例:
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;
}
Removing the final
modifier would result in compile error, because it isn't guaranteed anymore that the value is a runtime constant. Changing the value from outside the anonymous class would namely cause the anonymous class instance to behave different after the moment of creation.
删除final
修饰符会导致编译错误,因为不再保证该值是运行时常量。从匿名类外部更改值将导致匿名类实例在创建后表现不同。
回答by Erick G. Hagstrom
The final
keyword on a method parameter means absolutely nothing to the caller. It also means absolutely nothing to the running program, since its presence or absence doesn't change the bytecode. It only ensures that the compiler will complain if the parameter variable is reassigned within the method. That's all. But that's enough.
final
方法参数上的关键字对调用者毫无意义。它对正在运行的程序也绝对没有任何意义,因为它的存在与否不会改变字节码。它只能确保编译器在方法中重新分配参数变量时会报错。就这样。但这已经足够了。
Some programmers (like me) think that's a very good thing and use final
on almost every parameter. It makes it easier to understand a long or complex method (though one could argue that long and complex methods should be refactored.) It also shines a spotlight on method parameters that aren'tmarked with final
.
一些程序员(像我一样)认为这是一件非常好的事情,并且final
几乎用于每个参数。它使理解长或复杂的方法变得更容易(尽管有人可能会争辩说应该重构长而复杂的方法。)它还突出了未用标记的方法参数final
。
回答by Armand
@stuXnet, I could make the exact opposite argument. If you pass an object to a function, and you change the properties of the passed object then the caller of the function will see the changed value in its variable. This implies a pass by reference system, not pass by value.
@stuXnet,我可以提出完全相反的论点。如果您将一个对象传递给一个函数,并且您更改了传递对象的属性,则该函数的调用者将在其变量中看到更改后的值。这意味着传递引用系统,而不是传递值。
What is confusing is the definition of pass by value or pass by reference in a system where the use of pointers is completely hidden to the end user.
令人困惑的是在系统中按值传递或按引用传递的定义,其中指针的使用对最终用户完全隐藏。
Java is definitely NOT pass by value, as to be such, would mean one could mutate the passed object and the original would be unaffected.
Java 绝对不是按值传递,因此,这意味着可以改变传递的对象,而原始对象不受影响。
Notice you cannot mutate primitives you can only assign them to variables. So testing a Pass by reference or by value by using primitives is not a test.
请注意,您不能改变原语,您只能将它们分配给变量。因此,通过使用原语按引用或按值测试 Pass 不是测试。
What you cannot do in Java that can be done in other languages is to reassign the caller's variables to a new value because there are no pointers in Java, so this makes it confusing.
您在 Java 中不能做而在其他语言中可以做的事情是将调用者的变量重新分配给一个新值,因为 Java 中没有指针,所以这使它变得混乱。
回答by SilentKnight
finalmeans you can't change the value of that variable once it was assigned.
final意味着一旦分配了该变量的值,您就无法更改该值。
Meanwhile, the use of finalfor the arguments in those methods means it won't allow the programmer to change their value during the execution of the method. This only means that inside the method the finalvariables can not be reassigned.
同时,在这些方法中使用final作为参数意味着它不允许程序员在方法执行期间更改它们的值。这仅意味着在方法内部不能重新分配最终变量。
回答by Roopam
If you declare any parameter as final, you cannot change the value of it.
如果将任何参数声明为 final,则不能更改它的值。
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);
}
}
Output: Compile Time Error
输出:编译时错误
For more details, please visit my blog: http://javabyroopam.blogspot.com
更多详情请访问我的博客:http: //javabyroopam.blogspot.com
回答by ttati
final keyword in the method input parameter is not needed. Java creates a copy of the reference to the object, so putting final on it doesn't make the object final but just the reference, which doesn't make sense
不需要方法输入参数中的 final 关键字。Java 创建对象引用的副本,因此将 final 放在它上面不会使对象成为最终对象,而只是引用,这没有意义