1
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. Similarly, why is z null initially and after it is not null. What is happening in the code?

Yasel
  • 2,920
  • 4
  • 40
  • 48
paidedly
  • 1,413
  • 1
  • 13
  • 22
  • 4
    Initialization happens in order, from top to bottom. If you get rid of the `A` class and stick the logic into a method `a()`, it should be obvious what's going on. – Boris the Spider Mar 28 '15 at 12:45
  • shouldn't this statement int xyz=new B().show() give an error "Illegal forward reference" since show() uses c which has not been allocated memory yet? – paidedly Mar 28 '15 at 12:48
  • Why? That's another _class_. If you could only reference classes declared in order, Java would be a very odd language indeed... – Boris the Spider Mar 28 '15 at 12:48
  • Yes it is . But it makes use of c variable of class A ,which at this stage( xyz=new B().show() ) has not been created in memory. – paidedly Mar 28 '15 at 12:50
  • 2
    And that is exactly why [leaking `this` in a constructor](http://stackoverflow.com/questions/3921616/java-leaking-this-in-constructor) is considered an anti-pattern. – Boris the Spider Mar 28 '15 at 12:51

4 Answers4

3

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). Code of constructor is invoked after new will finish its job, and is responsible for setting up correct state for such empty object.

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. BUT code which initialized b and z

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.

This problem doesn't exist in case of second show()

lmn = z.show(); 

because now b and z are initialized.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
0

In your line 2 You are calling int xyz = new B().show(); // prints c=0 and z=null in the start.

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.

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 :)

Move your line 2 code to line 4 and it should print since variable are initialized now.

Om.
  • 2,532
  • 4
  • 22
  • 22
0

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). They are all allocated in memory with default values (c is int so 0, z is object so null [address is 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. 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.

Then when you execute:

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

Both c and z have gotten new values. But at all points in your code, they have been allocated and have had some value (first default).

Ori Lentz
  • 3,668
  • 6
  • 22
  • 28
0

When you create Object of A in class C as

A p = new A();

Default construction gets class and Object gets created with class member variables with default values. At this points values of class variables are as follows:

  • xyz = 0 (because it of type int)
  • c = 0 (because it is also int)
  • z = null (because it is reference)
  • lmn = 0 (because it if of type int)

Refer below screenshot to see the variable states

enter image description here

When it reaches to below statement for evaluating xyz values:

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.

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()

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.

enter image description here

so, it prints the value of C as -319 and z as hexadecimal values of object. (not null)

codiacTushki
  • 750
  • 1
  • 9
  • 22