3

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

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);
    }
}
4

3 回答 3

12

显然,这样的代码永远不会真正发生。太可怕了。我认为你不应该花太多时间担心它为什么给出 7,但实际上并不难理解为什么。

要评估的第一个字段值是InterfaceA.A,因此 VM 开始初始化InterfaceA。这需要InterfaceB.B,所以它开始初始化InterfaceB。这需要InterfaceC.C,所以它开始初始化InterfaceC

现在虽然InterfaceC.C是 引用InterfaceA.A,但 VM 已经在初始化InterfaceA,所以不管怎样它都会继续进行(根据JLS 的第 12.4.2 节):

如果 C 的 Class 对象指示当前线程正在对 C 进行初始化,那么这一定是对初始化的递归请求。释放LC并正常完成。

所以InterfaceA.A仍然是 0(我们仍在尝试计算它应该具有的值,而 0 是 的默认值int),并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行,您将对上述所有表达式得到相同的答案。)

于 2013-10-18T06:22:12.240 回答
6
System.out.println(A + B + C);

当您要求A( InterfaceB.B * 2;) 时,您需要B

所以,B 需要解决,

 int B = InterfaceC.C + 1;

当您要求B( InterfaceC.C + 1) 时,您需要C

所以,C 需要解决,

  int C = A + 1;       //  0+1 =1

A 尚未解决,默认为0

所以 intC1

现在,你需要B

  int B = InterfaceC.C + 1;   // 1+1  =2

现在

 int A = InterfaceB.B * 2;  // 2*2 =4

最后

1+2+4 =7

于 2013-10-18T06:22:15.247 回答
1

当您运行代码时,从方法开始执行。在mainmainSystem.out.println(A+B+C)中,正如您所知,控制从rightleft。在这种情况下C,首先执行(因为它存在于最右边)的意思c=A+1但是A is 0如此C=1

现在出现在soB的左侧,这意味着so (因为 c 已经是 1)CBB=C+1B=2

因为A是极端的left所以现在A被执行这意味着A=B*2 所以最后它4+2+1=7

同样,如果您打印System.out.println(B+C+A);,那么您将获得 3

于 2013-10-18T06:31:32.657 回答