为什么我在 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
实例。但是初始化 b
和 z
的代码
int c = -319;
B z = new B();
在您的第一个 show()
方法(使用 b
和 z
)之后发生,这意味着将显示它们的默认值。
第二个不存在这个问题show()
lmn = z.show();
因为现在 b
和 z
已经初始化了。
在您的 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;
}
}
在上面的代码中,您正在访问变量 c
和 Z
,它们是 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 打印为对象的十六进制值。 (非空)
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
实例。但是初始化 b
和 z
int c = -319;
B z = new B();
在您的第一个 show()
方法(使用 b
和 z
)之后发生,这意味着将显示它们的默认值。
第二个不存在这个问题show()
lmn = z.show();
因为现在 b
和 z
已经初始化了。
在您的 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;
}
}
在上面的代码中,您正在访问变量 c
和 Z
,它们是 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 打印为对象的十六进制值。 (非空)