我遇到了一个问题,我无法找出为什么它的输出会随着
7
当我用数学方法计算时,它的输出结果可以是7、8或任何其他数字。所以我的问题是,它仅在什么基础上得出7
interface InterfaceA
{
int A = InterfaceB.B * 2;
}
interface InterfaceB
{
int B = InterfaceC.C + 1;
}
interface InterfaceC extends InterfaceA
{
int C = A + 1;
}
public class TestInterface implements InterfaceA, InterfaceB, InterfaceC {
public static void main(String[] args) {
System.out.println(A + B + C);
}
}
最佳答案
显然,此类代码绝对不应实际发生。太恐怖了我认为您不应该花太多时间担心它为什么会给出7,但是实际上不难理解为什么。
要评估的第一个字段值为InterfaceA.A
,因此VM开始初始化InterfaceA
。这需要InterfaceB.B
,因此它开始初始化InterfaceB
。这需要InterfaceC.C
,因此它开始初始化InterfaceC
。
现在,尽管InterfaceC.C
引用了InterfaceA.A
,但虚拟机已经在初始化InterfaceA
,因此无论(根据JLS的section 12.4.2),它都可以继续进行:
如果C的Class对象指示当前线程正在进行C的初始化,则这必须是对初始化的递归请求。释放LC并正常完成。
因此InterfaceA.A
仍然为0(我们仍在尝试确定应具有的值,并且int
的默认值为0),而InterfaceC.C
的值为1(0 + 1)。然后InterfaceB.B
的值为2(1 + 1),而InterfaceA.A
的值为4(2 * 2)。
将所有这些字段值求和,最后得到7。
如果您使用不同的表达式,则会得到不同的值,因为您会看到最后初始化了一个不同的接口,尽管它仅取决于所引用的第一个字段:
A + B + C = 7 (A = 4, B = 2, C = 1)
A + C + B = 7 (A = 4, B = 2, C = 1)
B + A + C = 3 (A = 0, B = 2, C = 1)
B + C + A = 3 (A = 0, B = 2, C = 1)
C + A + B = 6 (A = 2, B = 1, C = 3)
C + B + A = 6 (A = 2, B = 1, C = 3)
(当然,您必须替换现有的代码行,因为这与类型初始化有关-如果仅添加更多
System.out.println
行,您将对上述所有表达式获得相同的答案。)