我遇到了一个问题,我无法找出为什么它的输出会随着

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行,您将对上述所有表达式获得相同的答案。)

07-26 09:27