通过getter访问最后一个字段的初始化
首先之前,这个问题具有着与这些漂亮的问题:通过getter访问最后一个字段的初始化
1)Use of uninitialized final field - with/without 'this.' qualifier
2)Why isn't a qualified static final variable allowed in a static initialization block?
但我会问它另一个角度来看。只是要记住:上述提到的问题被询问关于使用关键字this
在Java 7
中访问final
字段。
在我的问题中有类似的东西,但不一样。那么,考虑下面的代码:
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();
}
}
和输出是:
0
0
正如你可以看到这里有两个不清楚的事情:
- 没有访问非另一种合法的方式初始化的
final
字段:使用它的getter。 - 我们应该考虑的是空白决赛场上,它的分配新建分配FY
a = getA();
为法律将始终分配给它的默认值一样,根据JLS
非final
场?换句话说,它是否应该被视为预期的行为?
你真正遇到的是编译器的推理能力。 对于您的第一个编译器错误,由于编译器肯定知道未分配,所以失败。与第二个a = a相同(不能从a进行赋值,因为它绝对没有在此处指定)。 工作a = getA()的行是a的第一个单一明确赋值,所以这很好(不管值从何而来; getA()的实现无关紧要,并且此时不进行评估)。
getA()方法是有效的,并且可以返回一个值,因为实例初始值设定项已明确赋值给a。
对于一个看着它的人来说它是有道理的,但它并不是编译器内置的推理。每个独立评估的块都是有效的。
哪个“静态初始化器”?对不起,你在说什么? – Andremoniy 2014-08-29 17:27:06
对不起,实例初始值设定项(我已编辑更正)。 – user1676075 2014-08-29 18:38:46
您链接的问题具有JLS规定的规则。他们没有说任何关于调用方法的东西,所以这些都是允许的。 – 2014-08-29 18:46:32