45

为什么必须在构造函数完成之前初始化最终变量?

public class Ex
{
  final int q;
}

当我编译这段代码时,我得到这样的错误

错误:变量 q 可能尚未初始化

4

9 回答 9

37

官方的原因是它是由Java Language Specification 8.3.1.2定义的:

必须在声明它的类的每个构造函数的末尾明确分配一个空白的最终实例变量;否则会发生编译时错误。

空白 final 是一个 final 变量,其声明缺少初始化程序(即您所描述的)。

于 2012-07-05T13:26:34.977 回答
15

Because final prevents you from modifying variables, but it has to be initialized at some point, and the constructors is the right place to do so.

In your case, it would be called a blank final because it is not initialized when declared.

于 2012-07-05T13:14:21.510 回答
14

变量的值final只能设置一次。构造函数是类代码中唯一可以保证这一点成立的地方;构造函数只为一个对象调用一次,但其他方法可以调用任意次数。

于 2012-07-05T13:16:25.580 回答
11

必须final在声明或构造函数中初始化变量。

如果在构造函数返回时它还没有被初始化,它可能永远不会被初始化,并且可能仍然是一个未初始化的变量。编译器无法证明它将被初始化,因此会引发错误。

这个维基百科摘录很好地解释了它:

最终变量只能通过初始化程序或赋值语句初始化一次。它不需要在声明时初始化:这称为“空白最终”变量。必须在声明它的类的每个构造函数的末尾明确分配一个类的空白最终实例变量;同样,必须在声明它的类的静态初始化程序中明确地分配一个空白的 final 静态变量:否则,两种情况都会发生编译时错误。(注意:如果变量是引用,这意味着该变量不能重新绑定到引用另一个对象。但它引用的对象仍然是可变的,如果它最初是可变的。)

于 2012-07-05T13:20:21.810 回答
6

final应用于字段的关键字具有以下两种效果之一:

  • 在原语上,它防止原语的值被改变(一个 int 不能改变值)
  • 在一个对象上,它防止“变量的值”,即对对象的引用,被改变。也就是说,如果你有 a final HashMap<String,String> a,你将只能设置一次,你将不能再做this.a=new HashMap<String,String>();一次,没有什么能阻止你做this.a.put("a","b"),s 因为那不会修改引用,只是对象的内容。
于 2012-07-05T13:18:34.040 回答
2

The final modifier prevents your from changeing the variables value, hence you have to initialize it where you declare it.

于 2012-07-05T13:14:00.343 回答
0

Final修饰符不允许更改您的变量值。所以你需要在某个地方给它赋值,而构造函数是你在这种情况下必须这样做的地方。

于 2012-07-05T13:14:51.263 回答
0

语言规范包含关于最终变量和字段属性的特定保证,其中之一是正确构造的对象(即构造函数成功完成的对象)必须初始化其所有最终实例字段并且对所有线程可见。因此,编译器分析代码路径并要求您初始化这些字段。

于 2012-07-05T13:15:46.527 回答
0

如果一个实例变量用 final 关键字声明,则意味着它以后不能被修改,这使它成为一个常量。这就是为什么我们必须使用 final 关键字初始化变量。初始化必须显式完成,因为 JVM 不为最终实例变量提供默认值。最终实例变量必须在声明时初始化,例如:

class Test{
   final int num = 10;
   }

或者它必须在实例块中声明,例如:

class Test{
 final int x;
  {
   x=10;
  }
} 

或者必须在构造函数 COMPLETION 之前声明它,例如:

class Test{
 final int x;
  Test(){ 
   x=10;
  }
}

请记住,我们可以在构造函数块中对其进行初始化,因为初始化必须在构造函数完成之前完成。

于 2019-06-17T13:17:28.557 回答