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

时间:2015-03-28 12:43:15

标签: java oop object inner-classes

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获得null。同样,为什么z null最初和之后不是{{1}}。代码中发生了什么?

4 个答案:

答案 0 :(得分:3)

您需要知道new运算符负责创建类的实例(具有默认值的字段的实例:numeric:0; boolean:{ {1}},char:false,参考:'\0')。在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实例。但是初始化Ab

的代码
z

在您的第一个int c = -319; B z = new B(); 方法(使用show()b)后发生,这意味着将显示其默认值。

如果出现第二个z

,则此问题不存在
show()

因为现在lmn = z.show(); b已初始化。

答案 1 :(得分:0)

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,它们是类的成员变量,并且由于尚未初始化,因此它们已被分配了默认值。

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,因为变量现已初始化,所以应打印出来。

答案 2 :(得分:0)

使用足够的内存来实例化类以包含其所有“字段”。

当你这样做时:

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()的观点是它引用的所有字段都已定义/声明,或者至少已分配

然后当你执行:

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

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

答案 3 :(得分:0)

当您在C类中创建A的对象

A p = new A();

默认构造获取类,并使用具有默认值的类成员变量创建Object。此时,类变量的值如下:

  • xyz = 0(因为它的类型为int)
  • c = 0(因为它也是int)
  • z = null(因为它是参考)
  • lmn = 0(因为如果是int类型)

请参阅下面的屏幕截图,了解变量状态

enter image description here

当它达到以下语句以评估xyz值时:

int xyz = new B().show()

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

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

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

请参阅下面的屏幕截图,了解变量状态。

enter image description here

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