3

在我当前的项目中,我注意到方法中的所有类字段和变量都尽可能使用 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(...);
    ...
}

有什么理由这样做吗?

ps 据我所知,项目不应该是多线程的(至少我什么都没听说过)。

4

5 回答 5

4

当您编写 final 时,您是在向编译器和人类读者发出信号,表明此变量设置一次,然后不会更改。

编译器使用它来检查您是否不会意外地重新分配变量。如果你这样做,它会给出一个编译错误。

人类读者可以使用它来更快地理解代码的意图。

错过它通常不会导致您的代码失败,但如果您希望字段不更改,最好明确地说出来。另请注意,有时 final 是强制性的,例如在使用本地类时:

除了访问包含类定义的字段外,本地类还可以访问本地方法定义范围内并声明为 final 的任何局部变量、方法参数或异常参数。

另一方面,有时您确实希望能够重新分配给变量。显然,在这种情况下,您不应将其声明为 final。

于 2010-03-27T18:49:42.027 回答
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;
    }
于 2010-03-27T18:53:40.550 回答
2

不可变类本质上是线程安全的,您可以在其中安全地跨线程共享。如果您声明一个类的所有字段最终(并且该类本身是最终的)并且假设每个字段本身是不可变的,那么该对象将可以安全地跨线程共享。

于 2010-03-27T19:30:12.113 回答
0

理论上 JVM 可以更好地优化这些,但我不知道它是否真的可以。final用于指示您只能为变量赋值一次。

于 2010-03-27T18:50:20.060 回答
-1

实际上,该对象位于 2 个甚至更多类加载器(如应用服务器环境)中,因此甚至最终会被多次分配。或者从稍后更改的属性文件中加载声明的 final,这里发生将声明的 final 删除为普通变量变得更加实用。

于 2010-03-27T19:01:45.413 回答