当我编译代码时遇到问题。当我编译我的代码 foo2.var 在类 foo 中返回 null 时,我似乎不明白为什么。我在 foo2 类中进行静态初始化导致 foo2.var 在 foo 类中为 null 的方式是否有问题?
任何帮助表示赞赏。
public class foo extends bar {
public final static String blah = foo2.var;
...
}
public abstract class bar {
...
}
public class foo2 extends bar {
public final static String var;
static {
var = "newstring";
}
...
}
本例中 foo2.var 行出现空指针错误。
访问静态字段(其值不是编译时常量表达式)将触发声明该字段的类的初始化,在此期间执行静态初始化程序。然而,如果初始化器之间不存在循环依赖,则只能保证在读取字段时初始化已完成。
例如,如果您运行程序
class Bar {
static final long bar;
static {
System.out.println("Assigning bar");
bar = Foo.foo;
}
}
class Foo extends Bar {
static final long foo;
static {
System.out.println("Assigning foo");
foo = 1;
}
}
public class Test {
public static void main(String[] args) {
new Foo();
System.out.println(Bar.bar);
}
}
你会得到以下输出:
Assigning bar
Assigning foo
0
1
因为要创建一个新实例Foo
, Foo.class
被初始化,首先初始化其超类Bar.class
,它读取字段Foo.class
, but Foo.class
已经被初始化。 Java 语言规范要求第 12.4.2 节,步骤 3,这样的递归初始化立即完成,即调用者将看到该类处于部分初始化状态。那是,Foo.foo
在读取时未分配,因此仍包含默认值 0。该值被分配给Bar.bar
,完成初始化Bar.class
。然后,初始化Foo.class
通过运行初始化程序来恢复,该初始化程序设置Foo.foo
to 1.
实际上,您可能希望检查类的依赖关系并构建程序,以便初始化程序之间不存在循环依赖关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)