public interface AI {
public static final int A = BI.B+1;
}
public interface BI {
public static final int B = CI.C;
}
public interface CI extends AI {
public static final int C = A+1;
}
public class Test implements AI, CI, BI {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("A : " + A);
System.out.println("B : " + B);
System.out.println("C : " + C);
System.out.println(A+B+C);
}
}
O / p - > 4
有人可以帮助我理解输出4背后的代码流和逻辑吗? 感谢。
答案 0 :(得分:2)
在加载接口之前,不会设置接口中变量的值。它们由第一个语句加载:
System.out.println("A : " + A);
这会导致AI
被加载和初始化。它会尝试将A
的值设置为BI.B+1
。
这会导致BI
被加载和初始化。它会尝试将B
的值设置为C1.C
。
这会导致CI
被加载和初始化。这里,它扩展AI
的事实只允许A
被简单的名称引用。它设置为A+1
。技术上,AI
仍在初始化; A
中的AI
值尚未设置。在Java中,未设置的变量具有默认值,对于基本数字类型,该值为0
。
因此,'C'获得值1
,B
也获得1
。这意味着A
设置为2
。这就是前3个印刷语句的输出
A : 2
B : 1
C : 1
当然,这些值会添加到4
。
此外,我希望这只是一个谜题,而不是真正的代码;看来这个技巧允许人们在static final
初始化AI.A
之前将0
变量设置为CI
为C
。 JLS, Section 9.3.1,声明:
请注意,作为常量变量的接口字段(第4.12.4节)在其他接口字段之前初始化。这也适用于作为类中常量变量的静态字段(第8.3.2节)。永远不会观察到这些字段具有默认的初始值(§4.12.5),即使是狡猾的程序也是如此。
初始化static final
变量的值都不是常量表达式,因此它们不是常量变量。常量变量是使用常量表达式初始化的final
变量。这使得这是一个“狡猾的程序”。