在使用前初始化需要最终变量的真正原因是什么

时间:2016-04-09 20:38:33

标签: java language-lawyer final static-initialization object-construction

我知道:

  • 空白的最终类变量必须由声明它的类的静态初始化程序明确赋值,否则会发生编译时错误。

  • 必须在每个结尾处明确指定空白的最终实例变量 声明它的类的构造函数,或发生编译时错误。

但我不完全是为什么。 我真的很想知道造成这种情况的原因。

问题可以扩展到为什么这种限制不适用于非最终变量。

我认为不允许使用非初始化的最终变量的原因是相同的。 (同样的延伸适用。)如果我错了,请纠正我。

3 个答案:

答案 0 :(得分:2)

对于非final变量,这一点的推论是变量的initial value。每个字段都会根据其类型获得初始值 - 通常是0null的变体。

这里暗示,如果您声明变量为final,那么您有一个特定的值,您希望分配该变量,而不是在其运行中稍后更改。 Java不知道它是什么价值,它可能会消除为您自动声明这些值的便利性,从而不会干扰开发人员的意图。

要求所有final变量初始化,并且在使用之前支持所有变量为definitely assigned。您可以使用未初始化为某个值的非final字段 - 但它可能是null - 但您不能使用尚未初始化的局部变量出于同样的原因。

答案 1 :(得分:1)

首先,它不是针对null的东西。以下是合法的:

final String ABC;
{
    ABC = null;
}
static final String DEF;
static {
    DEF = null:
}
final String GHI = null;

这是以下决定:

  

当最终字段或局部变量未初始化时,它可以非常   好吧是一个bug,忘了初始化。   (对于普通字段,锅炉代码太多,并且提供了字段归零。)

对于局部变量,您可能会发现这很明显。因为最终变量只能分配一次,并且决定只在构造期间发生这种情况(否则你需要管理变量是否被初始化)。

答案 2 :(得分:1)

语言设计决策总是在灵活性和错误预防之间进行权衡。在这种情况下,有一些简单的问题需要检查:

如果存在代码路径,其中未分配final变量:

  • 开发人员声明final变量仅保留默认值null0false的可能性有多大?
  • 相比之下,开发人员忘记初始化或忽略可能的代码路径的可能性有多大,换句话说,拒绝此代码可以防止出现令人讨厌的错误?
  • 开发人员需要做多少工作才能编写显式赋值,如果(s)他真的想要默认值?

我认为,试图回答这些问题应该会导致这个设计决策背后的理由。

这是进行重要澄清的地方。对于局部变量,所有变量必须在使用前初始化。只有非final堆变量,读取,字段和数组元素才能解除限制。

对于数组,显而易见的是,为什么开发人员不能强制编写显式默认值,因为当数组可以实例化长度为2³¹的元素时。对于非final实例字段,可以讨论此决策。但是这样的讨论超出了Stackoverflow的范围......