在Java中,有一种惯例,将每个变量(局部变量或类)声明为final参数(如果它们确实是final的话)。
虽然这会使代码更加冗长,但这有助于容易阅读/掌握代码,也可以防止错误,因为意图被清晰地标记出来。
你对此有何看法?
在Java中,有一种惯例,将每个变量(局部变量或类)声明为final参数(如果它们确实是final的话)。
虽然这会使代码更加冗长,但这有助于容易阅读/掌握代码,也可以防止错误,因为意图被清晰地标记出来。
你对此有何看法?
当前回答
我认为这一切都与良好的编码风格有关。当然,你可以编写出好的、健壮的程序,而不需要在任何地方使用大量的最终修饰符,但当你考虑到……
将final添加到所有不应该更改的内容中,只会减少您(或下一个编写代码的程序员)误解或误用导致代码生成的思维过程的可能性。至少当他们现在想要改变你以前不变的东西时,它应该敲响一些警钟。
一开始,在你的代码中看到很多最终的关键字看起来有点尴尬,但很快你就会不再注意这个词本身,只会简单地想,从现在开始,这个东西永远不会改变(你可以从我这里得到;-)
我认为这是很好的练习。我并不是一直都在用它,但当我可以并且有意义的时候,我就会这样做。
其他回答
将类标记为final还可以使一些方法绑定发生在编译时而不是运行时。 考虑下面的“v2.foo()”——编译器知道B不能有子类,所以foo()不能被重写,所以要调用的实现在编译时是已知的。如果类B没有被标记为final,那么v2的实际类型可能是某个扩展B并重写foo()的类。
class A {
void foo() {
//do something
}
}
final class B extends A {
void foo() {
}
}
class Test {
public void t(A v1, B v2) {
v1.foo();
v2.foo();
}
}
我从不在局部变量上使用它们,没有什么意义。即使您不认为变量应该被重新赋值,这对于下一个改变代码的人来说也没有什么区别,而且由于代码正在被更改,任何使其最终的原始目的都可能不再有效。如果只是为了清晰,我认为它失败了,因为冗长的负面影响。
对于成员变量也是如此,因为它们提供的好处很少,除了常量的情况。
它也与不可变无关,因为不可变的最好指标是它被这样记录并且/或没有可以改变对象的方法(这与使类为final是保证它是不可变的唯一方法)。
但是,嘿,这只是我的观点:-)
最后一个修饰符,特别是对于变量,是一种让编译器强制执行通常合理的约定的方法:确保一个(局部或实例)变量只被赋值一次(不多不少)。通过确保变量在使用之前被明确赋值,你可以避免常见的NullPointerException:
final FileInputStream in;
if(test)
in = new FileInputStream("foo.txt");
else
System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned
通过防止变量被多次赋值,可以防止过宽的作用域。而不是这样:
String msg = null;
for(int i = 0; i < 10; i++) {
msg = "We are at position " + i;
System.out.println(msg);
}
msg = null;
我们鼓励你这样做:
for(int i = 0; i < 10; i++) {
final String msg = "We are at position " + i;
System.out.println(msg);
}
一些链接:
最后的故事(《Hardcore Java》一书的免费章节) 一些最终的模式 明确的任务
为事件监听器使用匿名本地类等是Java中的常见模式。 final关键字最常见的用法是确保偶数侦听器可以访问作用域内的变量。
但是,如果您发现自己被要求在代码中放入大量的最终语句。这可能是你做错事的好暗示。
上面的文章给出了这样一个例子:
public void doSomething(int i, int j) {
final int n = i + j; // must be declared final
Comparator comp = new Comparator() {
public int compare(Object left, Object right) {
return n; // return copy of a local variable
}
};
}
选择为每个方法中的每个参数输入final会让编码员和代码读者感到非常恼火。
一旦愤怒超出合理范围,切换到Scala,默认情况下参数是最终的。
或者,您总是可以使用代码样式工具,它将自动为您完成这些工作。所有ide都实现了它们或作为插件。