一个私有的不可访问的字段需要被声明为 final 吗?

4

在Servlet中,我有两个选项来初始化一个变量,我不希望在@Singleton Servlet的生命周期内更改它,我们称之为:

Field a;

字段a仅供servlet内部使用,没有访问器方法。为了简单起见,字段a是不可变的,比如一个字符串。

选项1 - 在构造函数中使用从ServletContext获得的依赖注入信息初始化该字段,使其变为:

private final Field a;

选项2 - 在重写的init(ServletConfig cfg)方法中利用从ServletConfig(和ServletContext)中获取的信息设置变量,使字段变为:

private Field a;

显然,我更希望将字段设为final,但该字段是私有的且未附加访问器方法,因此我是否仍应尝试将其设为final?

因此,总结一下,是否应在构造函数中初始化字段并使其为final,或者在init方法中初始化并将其保留为非final且没有访问器?

谢谢。


1
作为一般规则,尽可能将您的变量声明为“final”。 - Louis Wasserman
3个回答

2

显然,我更希望将字段设为 final,但该字段是私有的并且没有访问器方法,那么我是否仍然应该尝试使其成为 final?

是的。这样可以使您的意图更清晰。如果不是 final 的话,您愿意打赌没有人会在以后添加一个修改它的方法,但实际上代码却假定它不会被更改吗?


2

final的优势在于您不会在代码的某个地方无意中更改它。


1

除了清晰地记录您的意图并使您的代码更易于理解和维护外,final修饰符在多线程应用程序中提供了一些重要的保证。

虽然我不确定Servlet规范是否保证了这一点,但实际上,Servlet引擎应该使用一些内存屏障来确保新Servlet实例的内部状态对处理Servlet请求的所有线程都是可见的。这称为“安全发布”。

然而,通常情况下并非如此。您所描述的“选项2”是“有效不可变性”。对象具有一个字段,该字段不是final,但在构建或某些初始化步骤之后不允许修改该字段。但是,如果其他线程在没有经过内存屏障的情况下访问此对象,则可能无法看到初始化线程分配给该字段的值,即使该字段是在对象的构造函数中设置的!

然而,分配给final字段的对象构造期间的值保证对所有其他线程可见,即使对象本身未“安全发布”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接