从构造函数中分配 Final 变量 |方法不允许。为什么?

Assigning Final variables from constructors | not allowed from methods. Why?

练习一些代码示例,我遇到了这个: 我已经在 class 级别声明了 final 变量,并试图从方法中赋值,导致编译时错误(code-2)。但是从构造函数中它确实被分配了(code-1)。

代码-1:

class Immutable {

    private final int age;
    private final String name;

    private Immutable(int age, String name) {
        this.age = age;
        this.name = name;
    }

代码-2:

class Immutable {

    private final int age;
    private final String name;

    private void me() {
        this.age = 19;
        this.name = "name";
    }

当然,它们也可以在 class 级别分配,但不允许在构造函数中再次这样做,因为它们只允许声明一次。但是,为什么 final 变量在构造函数中赋值,而不是在方法中赋值?

形式上,此行为在 Java Language specification:

中定义

8.3.1.2. final Fields

A blank final instance variable must be definitely assigned (§16.9) at the end of every constructor (§8.8) of the class in which it is declared; otherwise a compile-time error occurs.

原因是编译器在任何其他方法中完成另一个赋值时检测变量是否已经被赋值将是巨大的努力(如果不是不可能的话)。构造函数只执行一次,而任何其他方法都可以执行多次 - 因此检查字段是否在构造函数中初始化对于编译器来说要容易得多。

构造函数执行一次。方法可以执行多次。对 final 变量的赋值只允许一次——就这么简单。 (如果可以在构造后为它们分配不同的值,它们就不会很 "final" 对吗?C# 允许多次设置只读变量,但仍然只能在构造函数中... Java 是只是比那更严格。)

But, why are final variables assigned in constructors and not from methods?

因为作为一个方法,即使你把方法设置成private,总有再次调用该方法的倾向。 publicprotected 的其他方法可能仍然可以调用它,并且可以在 class.

之外调用调用它的那些非私有方法

所以唯一允许值被赋值一次的地方是在构造函数中(它只会在对象被实例化时被调用)。