[英]Making java method arguments as final
final
在下面的代码之间有什么区别。 将参数声明为final
有什么好处吗?
public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){
return ....
}
public String changeTimezone(final Timestamp stamp, final Timezone fTz,
final Timezone toTz){
return ....
}
由于形式方法参数是一个局部变量,只有当它们声明为 final 时,您才能从内部匿名类访问它们。
这使您无需在方法主体中声明另一个局部最终变量:
void m(final int param) {
new Thread(new Runnable() {
public void run() {
System.err.println(param);
}
}).start();
}
摘录自The final word on the final 关键字
最终参数
以下示例声明了最终参数:
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 来确保两个索引 i 和 j 不会被方法意外重置。 这是防止错误更改参数值的潜在错误的一种方便方法。 一般来说,短方法是防止此类错误的更好方法,但最终参数可能是对您的编码风格的有用补充。
请注意,最终参数不被视为方法签名的一部分,并且在解析方法调用时被编译器忽略。 参数可以被声明为最终的(或不是),而不会影响方法被覆盖的方式。
final 阻止您为变量分配新值,这有助于发现拼写错误。 从风格上讲,您可能希望保持接收的参数不变并仅分配给局部变量,因此 final 将有助于强制执行该风格。
必须承认我很少记得使用 final 作为参数,也许我应该。
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;
}
它没有太大区别。 这只是意味着你不能写:
stamp = null;
fTz = new ...;
但你仍然可以写:
stamp.setXXX(...);
fTz.setXXX(...);
这主要是对跟随您的维护程序员的一个提示,即您不会在方法中间的某个地方为参数分配一个新值,因为它不明显,因此可能会导致混淆。
在 Java 中用于参数/变量的 final 关键字将引用标记为 final。 如果将对象传递给另一个方法,系统会创建引用变量的副本并将其传递给该方法。 通过将新引用标记为 final,您可以保护它们免于重新分配。 它有时被认为是一种很好的编码实践。
对于此方法的主体, final
关键字将防止意外重新分配参数引用,从而在这些情况下产生编译错误(大多数 IDE 会立即抱怨)。 有些人可能会争辩说,在可能的情况下一般使用final
会加快速度,但在最近的 JVM 中情况并非如此。
列出了我看到的两个优点:
从你的例子
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 ..
}
在一个复杂的方法中,将参数标记为 final 将有助于将这些参数意外解释为方法局部变量,并且重新分配为编译器将标记这些情况,如示例所示。
由于形式方法参数是一个局部变量,只有当它们声明为 final 时,您才能从内部匿名类访问它们。
- 过去(在 Java 8 之前 :-) )
明确使用“final”关键字会影响内部匿名类的方法变量的可访问性。
- 在现代(Java 8+)语言中,不需要这样的用法:
Java 引入了“有效最终”变量。 如果代码不暗示更改变量的值,则假定局部变量和方法参数是最终的。 因此,如果您在 Java8+ 中看到这样的关键字,您可以认为它是不必要的。 引入“有效最终”使我们在使用 lambda 时键入更少的代码。
它只是 Java 中的一种结构,可帮助您定义契约并坚持下去。 这里有一个类似的讨论: http : //c2.com/cgi/wiki?JavaFinalConsideredEvil
顺便说一句 - (如 twiki 所说),如果您遵循良好的编程原则并且完成重新分配/重新定义传入参数引用,则将 args 标记为 final 通常是多余的。
在最坏的情况下,如果你重新定义了 args 引用,它不会影响传递给函数的实际值——因为只传递了一个引用。
我说的是一般将变量和字段标记为 final - 不仅适用于方法参数。 (将方法/类标记为 final 是完全不同的事情)。
这对你的代码的读者/未来的维护者有好处。 再加上一个合理的变量名称,它有助于让代码的读者看到/理解所讨论的变量所代表的内容,并让他们放心——而且让读者放心,只要您在同一范围内看到变量,意义就会保持不变相同,因此(她)他不必总是挠头去弄清楚变量在每种情况下的含义。 我们已经看到太多滥用变量“重用”的情况,这使得即使是简短的代码片段也难以理解。
final 关键字阻止您为参数分配新值。 我想用一个简单的例子来解释这一点
假设我们有一个方法
方法1(){
日期 dateOfBirth =new Date("1/1/2009");
方法2(出生日期);
方法3(出生日期); }
公共方法2(出生日期){
....
....
....
}公共方法2(出生日期){
....
....
....
}
在上述情况下,如果在方法 2 中为“dateOfBirth”分配了新值,那么这将导致方法 3 的输出错误。 因为传递给method3的值不是传递给method2之前的值。 所以为了避免这个 final 关键字用于参数。
这也是 Java 编码最佳实践之一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.