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

What is true reason for initiliazing need of final varibles before use

我知道:

为什么 final 变量不能在任何时候只赋值一次,而只能在声明时赋值?

对于非final 变量,此推论是变量的initial value。每个字段根据其类型接收一个初始值 - 通常是 0null.

的变体

这里暗示,如果您将一个变量声明为 final,那么您心中有一个特定的值,您希望该变量被赋值并且以后在其 运行。 Java 不知道那是什么值,它可能会剥夺自动为您声明这些值的便利性,以免干扰开发人员的意图。

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

首先不是反对null的东西。以下也是合法的:

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

这是以下决定:

When a final field or a local variable is not initialized it can very well be a bug, forgetting to initialize. (For normal fields it would be too much boiler code, and zeroing of fields is provided.)

对于局部变量,您可能会发现这一点很明显。由于 final 变量只能被赋值一次,并且决定这应该只在构造期间发生(否则你需要管理变量是否被初始化)。

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

如果有代码路径未分配 final 变量:

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

我认为,试图回答这些问题应该会引出这个设计决定背后的基本原理。

这是一个重要说明的地方。如果是局部变量,所有变量必须在使用前初始化。仅针对非 final 堆变量、读取、字段和数组元素解除限制。

在数组的情况下,当数组可以实例化的长度最多为 2³¹ 个元素时,为什么不强制开发人员编写显式默认值应该是显而易见的。对于非 final 实例字段,可以讨论此决定。但是这样的讨论超出了 Whosebug 的范围……