解释包含接口的java代码的输出

解释包含接口的java代码的输出,java,algorithm,math,interface,Java,Algorithm,Math,Interface,我遇到了一个问题,我无法找出为什么它的产出会如此巨大 七, 当我用数学方法计算时,它可以产生7,8或任何其他数字的输出,所以我的问题是,它是在什么基础上才变成7的 interface InterfaceA { int A = InterfaceB.B * 2; } interface InterfaceB { int B = InterfaceC.C + 1; } interface InterfaceC extends InterfaceA { int C = A

我遇到了一个问题,我无法找出为什么它的产出会如此巨大

七,

当我用数学方法计算时,它可以产生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,但事实上不难理解为什么

要计算的第一个字段值是
interfaceea.A
,因此VM开始初始化
interfaceea
。这需要
InterfaceB.B
,因此它开始初始化
InterfaceB
。这需要
InterfaceC.C
,因此它开始初始化
InterfaceC

现在,尽管
interfaceec.C
指的是
interfaceea.A
,但虚拟机已经在初始化
interfaceea
,因此它将继续进行(根据JLS):

如果C的类对象指示当前线程正在对C进行初始化,那么这必须是一个递归的初始化请求。释放信用证并正常完成

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

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

所以,
B
需要解决

 int B = InterfaceC.C + 1;
  int C = A + 1;       //  0+1 =1
当您要求
B
InterfaceC.C+1
)时,您需要
C

所以,
C
需要解决

 int B = InterfaceC.C + 1;
  int C = A + 1;       //  0+1 =1
A尚未解析,默认值为
0

所以int
C
1

现在,您需要
B

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

最后


1+2+4=7

运行代码时,从
main
方法开始执行。在main中,它的
System.out.println(A+B+C)
控制从
。
在这种情况下,首先执行
C
(因为它位于最右边),意思是
C=A+1
,但是
A是0
,所以
C=1

现在
B
出现在
C
的左侧,因此将执行
B
,这意味着
B=C+1
so
B=2
(因为C已经是1)

由于
A
处于极端
左侧
因此现在执行
A
,这意味着
A=B*2
所以最后它的
4+2+1=7


同样,如果您打印
System.out.println(B+C+A)然后你会得到3

你试过使用调试器吗?是的,我试过了,但我不知道它是基于什么基础来获取这些值的。你不应该在现实中看到这样的代码。我不认为有必要担心这样可怕的代码最终会做什么。@JonSkeet你是对的,但我在所有采访中都经常看到这样的问题,这是我最近的采访中提到的。所以我应该用这个平台来获取更多knowledge@ankit当前位置在我看来,这是一个非常糟糕的面试问题。我会对任何提出这样一个问题的面试官感到失望。