在我当前的项目中,我注意到只要有可能,所有类字段和变量内部方法都会使用final修饰符声明。
就像这里:
private final XMLStreamWriter _xmlStreamWriter;
private final Marshaller _marshaller;
private final OutputStream _documentStream;
private final OutputStream _stylesStream;
private final XMLStreamWriter _stylesStreamWriter;
private final StyleMerger _styleMerger;
public DocumentWriter(PhysicalPackage physicalPackage) throws IOException {
final Package pkg = new Package(physicalPackage);
final Part wordDocumentPart = pkg.createPart(
"/word/document.xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
// styles.xml
final Pair<Part, String> wordStylesPart = wordDocumentPart.createRelatedPart(...);
...
}
有没有理由这样做?
P.S。据我所知,项目不应该是多线程的(至少我没有听说过它)。
答案 0 :(得分:4)
当你写下final时,你向编译器和人类读者发出信号,告知这个变量设置一次然后不改变。
编译器使用它来检查您是否意外重新分配变量。如果这样做,将产生编译错误。
人类读者可以使用它来更快地理解代码的意图。
错过它通常不会导致代码失败,但如果你想要一个字段不改变,最好明确说明。另请注意,有时候final是必需的,例如使用本地类时:
除了访问由包含类定义的字段之外,本地类还可以访问本地方法定义范围内并声明为final的任何局部变量,方法参数或异常参数。
另一方面,有时您可能希望能够重新分配给变量。显然,在这种情况下,你不应该宣布它为最终版。
答案 1 :(得分:4)
在编程中,最好得到编译器错误而不是逻辑错误。编译器错误可在几秒钟内找到,并且可以非常快地得到纠正。
final关键字可以帮助将逻辑错误转换为编译器错误而不需要太多努力。
例如:
public int test(int num){
num = 10;
x = num*2
return x;
}
在上面的示例中,我们可能会意外地为num变量赋值,因此返回值将是错误的。使用final关键字,我们可以防止出现此类错误。
public int test(final int num){
num = 10; //compiler error
x = num*2
return x;
}
答案 2 :(得分:2)
不可变类本质上是线程安全的,您可以跨线程安全地共享。如果你声明一个类的所有字段为final(并且类本身是final),也假设每个字段本身都是不可变的,那么该对象可以安全地跨线程共享。
答案 3 :(得分:0)
从理论上讲,JVM可以更好地优化它们,但我不知道它是否确实如此。 final 用于表示您只能为变量赋值一次。
答案 4 :(得分:-1)
实际上,对象是2个甚至更多的类加载器,比如应用程序服务器环境,因此最终会被分配多次。或者从一个属性文件加载一个声明的final后来改变,发生在这里删除声明的final到normal变量得到了更实用。