为什么我在 Java 代码中得到两个不同的输出

Why am I getting two different outputs in Java code

class A {
    int xyz = new B().show(); // prints c=0 and z=null
    int c = -319;
    B z = new B();
    int lmn = z.show(); // prints c=-319

    class B {
        int show() {
            System.out.println("c=" + c);
            System.out.println("z=" + z);
            return -555;
        }
    }
}

class C {
    public static void main(String args[]) {
        A p = new A();
    }
}

为什么我一开始是 c=0,后来又是 c=-319。同样,为什么z开始是null,之后不是null。代码中发生了什么?

您需要知道 new 运算符负责创建 class 的 empty 实例(具有默认值的字段的实例:数字: 0;布尔值:false,字符:'[=19=]',引用:null)。构造函数代码在 new 完成其工作后调用,并负责为此类空对象设置正确的状态。

现在字段的初始化发生在构造函数中,因此您的代码

class A {
    int xyz = new B().show(); // prints c=0 and z=null
    int c = -319;
    B z = new B();
    int lmn = z.show(); // prints c=-319

    class B {
        int show() {
            System.out.println("c=" + c);
            System.out.println("z=" + z);
            return -555;
        }
    }
}

与(注意默认值)相同

class A {

    int xyz = 0;    //default values
    int c = 0;      //
    B z = null;     //
    int lmn = 0;    //

    A(){
        xyz = new B().show(); 
        c = -319;
        z = new B();
        lmn = z.show(); 
    }
    class B {
        int show() {
            System.out.println("c=" + c);
            System.out.println("z=" + z);
            return -555;
        }
    }
}

还有

xyz = new B().show();

相同
xyz = this.new B().show();

如此创建的 B 实例将可以访问在当前 A 构造函数中初始化的 A 实例。但是初始化 bz

的代码
int c = -319;
B z = new B();

在您的第一个 show() 方法(使用 bz)之后发生,这意味着将显示它们的默认值。

第二个不存在这个问题show()

lmn = z.show(); 

因为现在 bz 已经初始化了。

在您的 line 2 中,您在开始时呼叫 int xyz = new B().show(); // prints c=0 and z=null

调用

class B {
        int show() {
            System.out.println("c=" + c);
            System.out.println("z=" + z);
            return -555;
        }
    }

在上面的代码中,您正在访问变量 cZ,它们是 class 的成员变量,并且由于尚未初始化,因此它们被分配了默认值。

boolean                     =>  false
char                        =>  \u0000
int,short,byte / long       =>  0 / 0L
float /double               =>  0.0f / 0.0d
any reference type          =>  null

在你的情况下 ìnt 分配给 0 并且对象引用分配给 null :)

将您的 line 2 代码移至 line 4,它应该打印出来,因为现在变量已经初始化。

Class 实例化时有足够的内存来包含它的所有字段。

当你这样做时:

A p = new A();

这会为 A 及其字段(xyz、c、z 和 lmn)分配内存。它们都以默认值分配在内存中(c 是 int 所以是 0,z 是对象所以是 null [地址是 0x00])。

当你运行:

int xyz = new B().show(); // prints c=0 and z=null

您正在创建 B 的新实例。当该实例引用 c 和 z 时,它会打印它们的值。目前它们是默认值。出于所有意图和目的,show() 的观点是它引用的所有字段都已定义/声明,或者至少 allocated.

然后当你执行:

B z = new B();
int lmn = z.show(); // prints c=-319

c 和 z 都获得了新的值。但是在您的代码中的所有点,它们都已分配并具有一些值(第一个默认值)。

当您在 class C 中创建 A 的对象时

A p = new A();

默认构造得到 class 并且使用具有默认值的 class 成员变量创建对象。此时class个变量的值如下:

  • xyz = 0(因为它是 int 类型)
  • c = 0(因为也是int)
  • z = null(因为是引用)
  • lmn = 0(因为它是 int 类型)

参考下面的截图查看变量状态

当它到达下面的语句来评估 xyz 值时:

int xyz = new B().show()

它打印尚未完成初始化的 c 和 z 的值,因此我们将分别获得这些变量的默认值 0 和 NULL。

第二次时,程序调用class的show()方法 B.所有变量初始化已经完成,因为下面的语句一直执行到我们到达z.show的时候()

int c = -319;
b z= new (B); // call the default constructor of B to create object

请参阅下面的屏幕截图以查看变量状态。

因此,它将 C 的值打印为 -319,将 z 打印为对象的十六进制值。 (非空)