在Java中,有一种惯例,将每个变量(局部变量或类)声明为final参数(如果它们确实是final的话)。
虽然这会使代码更加冗长,但这有助于容易阅读/掌握代码,也可以防止错误,因为意图被清晰地标记出来。
你对此有何看法?
在Java中,有一种惯例,将每个变量(局部变量或类)声明为final参数(如果它们确实是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》一书的免费章节) 一些最终的模式 明确的任务
其他回答
听起来,反对使用最后一个关键字的最大论点之一是“这是不必要的”,而且它“浪费空间”。
如果我们承认“final”的许多好处,同时承认它需要更多的输入和空间,我认为Java应该默认将变量设置为“final”,并且如果编码器想要的话,就要求将变量标记为“mutable”。
我已经编写了一段时间的代码,并尽可能使用final。这样做了一段时间后(对于变量、方法参数和类属性),我可以说90%(或更多)的变量实际上是最终的。我认为在你不想修改变量的时候不修改变量的好处(我以前看到过,有时这很痛苦)是为了在你的代码中额外的输入和额外的“final”关键字。
也就是说,如果我要设计一种语言,我将使每个变量都是final,除非被其他一些关键字修改。
对于类和方法,我不太使用final。这是一个或多或少复杂的设计选择,除非您的类是一个实用程序类(在这种情况下,您应该只有一个私有构造函数)。
我也使用Collections.unmodifiable…在我需要的时候创建不可修改的列表
当在Java中与变量一起使用时,Final提供了c++中常量的替代品。所以当final和static被用于一个变量时,它就变成了不可变的。同时让迁移的c++程序员非常开心;-)
当与引用变量一起使用时,它不允许您重新引用对象,尽管对象可以被操作。
当final与方法一起使用时,它不允许子类重写该方法。
一旦用法非常清楚,就应该谨慎使用。这主要取决于设计,因为在方法上使用final不利于多态性。
只有当你非常确定变量的值不会/不应该被改变时,才应该将它用于变量。还要确保您遵循SUN鼓励的编码约定。int COLOR_RED = 1;(大写字母以下划线分隔)
对于引用变量,只在需要对特定对象的不可变引用时使用它。
关于可读性部分,在使用最终修饰语时,注释起着非常重要的作用。
我从来没有遇到过在变量上有最后一个关键字就能阻止我犯错误的情况,所以目前我认为这是一种巨大的浪费时间。
除非有真正的理由这样做(比如你想要明确指出变量是final的),否则我宁愿不这样做,因为我发现这样做会使代码的可读性降低。
但是,如果您没有发现它会使代码更难阅读或更长时间地编写,那么无论如何都可以使用它。
编辑:作为一个澄清(并试图赢回反对票),我不是说不要将常量标记为最终值,我是说不要做这样的事情:
public String doSomething() {
final String first = someReallyComplicatedExpressionToGetTheString();
final String second = anotherReallyComplicatedExpressionToGetAnother();
return first+second;
}
在我看来,这只是让代码更难阅读。
同样值得记住的是,所有final的作用都是防止你重新分配变量,它并没有使它成为不可变或类似的东西。
为:
Final fields - Marking fields as final forces them to be set by end of construction, making that field reference immutable. This allows safe publication of fields and can avoid the need for synchronization on later reads. (Note that for an object reference, only the field reference is immutable - things that object reference refers to can still change and that affects the immutability.) Final static fields - Although I use enums now for many of the cases where I used to use static final fields.
考虑但审慎地使用:
最终类——框架/API设计是我唯一考虑的情况。 Final方法——基本上与Final类相同。如果你疯狂地使用模板方法模式,并把东西标记为final,你可能太依赖继承而不是委托。
忽略,除非感觉肛门:
Method parameters and local variables - I RARELY do this largely because I'm lazy and I find it clutters the code. I will fully admit that marking parameters and local variables that I'm not going to modify is "righter". I wish it was the default. But it isn't and I find the code more difficult to understand with finals all over. If I'm in someone else's code, I'm not going to pull them out but if I'm writing new code I won't put them in. One exception is the case where you have to mark something final so you can access it from within an anonymous inner class.