我知道:
空白的最终类变量必须由声明它的类的静态初始化程序明确赋值,否则会发生编译时错误。
必须在每个结尾处明确指定空白的最终实例变量 声明它的类的构造函数,或发生编译时错误。
但我不完全是为什么。 我真的很想知道造成这种情况的原因。
问题可以扩展到为什么这种限制不适用于非最终变量。
我认为不允许使用非初始化的最终变量的原因是相同的。 (同样的延伸适用。)如果我错了,请纠正我。
答案 0 :(得分:2)
对于非final
变量,这一点的推论是变量的initial value。每个字段都会根据其类型获得初始值 - 通常是0
或null
的变体。
这里暗示,如果您声明变量为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
变量仅保留默认值null
,0
或false
的可能性有多大?我认为,试图回答这些问题应该会导致这个设计决策背后的理由。
这是进行重要澄清的地方。对于局部变量,所有变量必须在使用前初始化。只有非final
堆变量,读取,字段和数组元素才能解除限制。
对于数组,显而易见的是,为什么开发人员不能强制编写显式默认值,因为当数组可以实例化长度为2³¹的元素时。对于非final
实例字段,可以讨论此决策。但是这样的讨论超出了Stackoverflow的范围......