通过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?

但我会问它另一个角度来看。只是要记住:上述提到的问题被询问关于使用关键字thisJava 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 

正如你可以看到这里有两个不清楚的事情:

  1. 没有访问非另一种合法的方式初始化的final字段:使用它的getter。
  2. 我们应该考虑的是空白决赛场上,它的分配新建分配FY a = getA();法律将始终分配给它的默认值一样,根据JLSfinal场?换句话说,它是否应该被视为预期的行为?
+0

您链接的问题具有JLS规定的规则。他们没有说任何关于调用方法的东西,所以这些都是允许的。 – 2014-08-29 18:46:32

你真正遇到的是编译器的推理能力。 对于您的第一个编译器错误,由于编译器肯定知道未分配,所以失败。与第二个a = a相同(不能从a进行赋值,因为它绝对没有在此处指定)。 工作a = getA()的行是a的第一个单一明确赋值,所以这很好(不管值从何而来; getA()的实现无关紧要,并且此时不进行评估)。

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

对于一个看着它的人​​来说它是有道理的,但它并不是编译器内置的推理。每个独立评估的块都是有效的。

+0

哪个“静态初始化器”?对不起,你在说什么? – Andremoniy 2014-08-29 17:27:06

+0

对不起,实例初始值设定项(我已编辑更正)。 – user1676075 2014-08-29 18:38:46