在初始化之前通过getter访问最终字段

And*_*niy 5 java compiler-errors

首先,这个问题与这些好问题有着前瞻性的关系:

1)使用未初始化的最终字段 - 有/没有'这个'.预选赛

2)为什么静态初始化块中不允许合格的静态最终变量?

但我会从另一个角度来看它.只是要记住:上面提到的问题是关于final使用关键字thisin 进入字段的问题Java 7.

在我的问题中有类似的东西,但不一样.好吧,请考虑以下代码:

public class TestInit {
    final int a;
    {
        // System.out.println(a);   -- compile error
        System.out.println(getA());
        // a = a;                   -- compile error
        a = getA();
        System.out.println(getA());
    }
    private int getA() {
        return a;
    }
    public static void main(String[] args) {
        new TestInit();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

0
0
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这里有两个不清楚的事情:

  1. 还有另一种合法的方法来访问非初始化final字段:使用其getter.
  2. 我们是否应该将一个分配a = getA();视为空白最终字段的合法分配,并且它总是将其分配给它的默认值,就像final根据非字段一样JLS?换句话说,它应该被视为预期行为吗?

use*_*075 0

您真正遇到的是编译器的推理能力。对于您的第一个编译器错误,该错误会失败,因为编译器肯定知道 a 未分配。与第二个 a=a 相同(您不能从 a 进行分配,因为此时它绝对没有分配)。工作 a=getA() 的行是 a 的第一个、单一的、明确的赋值,所以这很好(无论值来自哪里;getA() 的实现并不重要,此时不进行评估) 。

方法 getA() 是有效的并且可以返回 a,因为实例初始值设定项已明确为 a 赋值。

这对于人类来说是有意义的,但它不是编译器中内置的推论。每个块经过独立评估都是有效的。