问题描述
我找到了这段代码here,恰好是Example 12.4.1-3. Interface Initialization Does Not Initialize Superinterfaces
,位于给定地址的下方。
interface I {
int i = 1,ii = Test.out("ii",2);
}
interface J extends I {
int j = Test.out("j",3),jj = Test.out("jj",4);
}
interface K extends J {
int k = Test.out("k",5);
}
class Test {
public static void main(String[] args) {
System.out.println(J.i);
System.out.println(K.j);
}
static int out(String s,int i) {
System.out.println(s + "=" + i);
return i;
}
}
答案是:
1
j=3
jj=4
3
问题是:jj=4
的打印方式是什么?
解决方法
如果JVM需要初始化接口,那么它将在接口中进行所有初始化,而不仅仅是您正在访问的变量。
在这种情况下,它不需要初始化I
,因为它使用的是常量字段,不会触发初始化,但是 did 需要初始化{{ 1}},因为它使用的不是编译时常量表达式J
。这样做意味着两个变量都将初始化。
编译器将K.j
转换为J.j
。因此,您的代码中没有实际引用K
。
您不会在输出中看到ii=2
,因为System.out.println(J.i);
的{{1}}值被内联,因此在代码中没有对I.i
的引用。