Java:为什么在定义字段之前引用字段时没有警告?

use*_*016 10 java static initialization inner-classes

在定义或初始化静态字段之前,不能引用静态字段:

static Integer j = i; /* compile error */
static final Integer i = 5;
Run Code Online (Sandbox Code Playgroud)

但是,当从实例初始化块(在匿名内部类中)引用它时,甚至不会生成警告.

见例子:

class StaticInitialization {

    static final Object o = new Object() {{
        j = i;
    }};

    static Integer j, k;
    static final Integer i = 5;

    static final Object o2 = new Object() {{
        k = i;
    }};
}
Run Code Online (Sandbox Code Playgroud)

结果是:j == null,k == 5显然我们已经做了引用,命令很重要,没有警告或编译错误.

这段代码合法吗?

Tho*_*s W 1

这段代码合法吗?大概。我不认为编译器的工作是分析对象实例化在破坏静态变量时故意产生的副作用。

对同一类中其他静态变量的“引用前声明”的有限分析实际上只是针对最常见的错误的帮助,而不是针对间接错误的铁定保证。

对于“引用之前声明”分析的范围仅限于直接访问其他static声明中的静态变量,我真的一点也不感到惊讶。这是一个简单而紧凑的分析,具有最小的复杂性并且速度非常快。

将其扩展以考虑对象实例化和方法调用的副作用,OTOH,将需要静态程序分析的权重和范围增加 20-1000 倍。静态分析可能需要访问整个已编译的程序代码,并通过基于约束的计算来确定可能发生的情况,以及可能在几分钟内运行的时间。

考虑到这些选择,从 Java 语言设计者的角度来看,选择仅涵盖同一类中字段的直接访问的简单分析是相当容易的。