简体   繁体   English

为什么我在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();
    }
}

Why am I getting c=0 initially and then c=-319 later. 为什么我最初得到c=0然后c=-319 Similarly, why is z null initially and after it is not null . 类似地,为什么z null最初并且在它不为null What is happening in the code? 代码中发生了什么?

You need to know that new operator is responsible for creating empty instance of class (instance with fields which will have default values: numeric: 0 ; boolean: false , char: '\\0' , reference: null ). 您需要知道new运算符负责创建类的实例(具有默认值的字段的实例:numeric: 0 ; boolean: false ,char: '\\0' ,reference: null )。 Code of constructor is invoked after new will finish its job, and is responsible for setting up correct state for such empty object. new完成其工作后调用构造函数代码,并负责为此类空对象设置正确的状态。

Now initialization of fields happens in constructor, so your 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;
        }
    }
}

is is same as (notice default values) 与(通知默认值)相同

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

Also

xyz = new B().show();

is same as 和...一样

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

so created instance of B will have access to instance of A which is initialized in current A constructor. 因此,创建的B实例将可以访问在当前A构造函数中初始化的A实例。 BUT code which initialized b and z 但是初始化bz代码

int c = -319;
B z = new B();

happens after your first show() method (which uses b and z ) which means that their default values will be shown. 在您的第一个show()方法(使用bz )之后发生,这意味着将显示它们的默认值。

This problem doesn't exist in case of second show() 在第二个show()情况下不存在此问题

lmn = z.show(); 

because now b and z are initialized. 因为现在bz被初始化了。

In your line 2 You are calling int xyz = new B().show(); // prints c=0 and z=null 在你的line 2你正在调用int xyz = new B().show(); // prints c=0 and z=null int xyz = new B().show(); // prints c=0 and z=null in the start. int xyz = new B().show(); // prints c=0 and z=null在开头int xyz = new B().show(); // prints c=0 and z=null

Which calls 哪个电话

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

in above code you are accessing variable c and Z which are member variables of class and since not initialized yet they been assigned default values. 在上面的代码中,您正在访问变量cZ ,它们是类的成员变量,并且由于尚未初始化,因此它们已被分配了默认值。

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

In your case ìnt assigned to 0 and object reference assigned to null :) 在你的情况下, ìnt分配给0 ,对象引用分配给null :)

Move your line 2 code to line 4 and it should print since variable are initialized now. line 2代码移动到line 4 ,它应该打印,因为变量现在已初始化。

Class is instantiated with sufficient memory to contain all its' fields. 类被实例化,具有足够的内存以包含其所有'字段。

When you do: 当你这样做时:

A p = new A();

This allocates memory for A and its' fields (xyz, c, z and lmn). 这为A及其'字段(xyz,c,z和lmn)分配内存。 They are all allocated in memory with default values (c is int so 0, z is object so null [address is 0x00]). 它们都在内存中分配了默认值(c是int所以0,z是对象所以null [地址是0x00])。

When you run: 当你运行:

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

You're creating a new instance of B. When that instance references c and z, it prints their values. 您正在创建B的新实例。当该实例引用c和z时,它会打印它们的值。 Currently they are default values. 目前它们是默认值。 For all intents and purposes, show()'s perspective is that all of the fields it references have been defined / declared, or at the very least allocated . 对于所有意图和目的,show()的观点是它引用的所有字段都已定义/声明,或者至少已分配

Then when you execute: 然后当你执行:

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

Both c and z have gotten new values. c和z都有了新的价值。 But at all points in your code, they have been allocated and have had some value (first default). 但是在代码中的所有点上,它们都已被分配并具有一些值(首先是默认值)。

When you create Object of A in class C as 在C类中创建A的Object时

A p = new A();

Default construction gets class and Object gets created with class member variables with default values. 默认构造获取类,并使用具有默认值的类成员变量创建Object。 At this points values of class variables are as follows: 此时,类变量的值如下:

  • xyz = 0 (because it of type int) xyz = 0(因为它的类型为int)
  • c = 0 (because it is also int) c = 0(因为它也是int)
  • z = null (because it is reference) z = null(因为它是引用)
  • lmn = 0 (because it if of type int) lmn = 0(因为如果是int类型)

Refer below screenshot to see the variable states 请参阅下面的屏幕截图以查看变量状态

在此输入图像描述

When it reaches to below statement for evaluating xyz values: 当它达到以下语句以评估xyz值时:

int xyz = new B().show()

it prints value of c and z whose initialization is yet to done so we will get defaults values of those variables as 0 and NULL respectively. 它打印了初始化尚未完成的c和z的值,因此我们将这些变量的默认值分别设置为0和NULL。

When 2nd time, program calls show() method of class B. All variables initialization has been done because below statements are executed till the time we reaches to z.show() 第二次,程序调用类B的show()方法。所有变量初始化都已完成,因为下面的语句一直执行到我们到达z.show()的时候

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

Refer to below screenshot to see the variable states. 请参阅下面的屏幕截图以查看变量状态。

在此输入图像描述

so, it prints the value of C as -319 and z as hexadecimal values of object. 因此,它将C的值打印为-319,将z打印为对象的十六进制值。 (not null) (不是null)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM