0

I have this code and the output is different from expected. Test t1 is already being overwritten but still keeping its initial value. Why is that happening?

public class Test2 {
        Test t1 = new Test(1);

        Test2(int i) {
            t1 = new Test(i);
        }

    public static void main(String[] args) {    
         Test2 t2 = new Test2(5);
         Test2 t3 = new Test2(15);
    }
}
class Test {
    Test(int x) {
        System.out.println("Constructor called " + x);
    }
}

Output is:

Constructor called 1
Constructor called 5
Constructor called 1
Constructor called 15
8
  • What are you expecting to get? Commented Oct 29, 2017 at 12:02
  • 1
    What do you mean by "but still keeping its initial value"? Commented Oct 29, 2017 at 12:02
  • 1
    Nothing is being overriden in your code. Commented Oct 29, 2017 at 12:03
  • I wasn't expecting "Constructor called 1" Commented Oct 29, 2017 at 12:03
  • 1
    What do you think Test t1 = new Test(1); should do then? What makes you think so? Commented Oct 29, 2017 at 12:04

4 Answers 4

2

You seem to expect your code to be equivalent to

public class Test2 {
        Test t1;

        Test2(int i) {
            t1 = new Test(i);
        }
    ...
}

Actually, it's equivalent to

public class Test2 {
        Test t1;

        Test2(int i) {
            t1 = new Test(1);
            t1 = new Test(i);
        }
    ...
}

The code in the constructor doesn't replace default initialization; instead, initializers run before the constructor.

Sign up to request clarification or add additional context in comments.

Comments

1
 public class Test2 {
        Test t1 = new Test(1); // you are creating Test class twice with argument 1 so output will be 1.

        Test2(int i) {
            t1 = new Test(i); // i = 5 and 15 
        }

    public static void main(String[] args) {    
         Test2 t2 = new Test2(5);   // Here you create 2 new instances so constructor called twice
         Test2 t3 = new Test2(15);
    }
}
class Test {
    Test(int x) {
        System.out.println("Constructor called " + x);
    }
}

Comments

0

Your question Why is that happening?

Because every time you initialize Test2, its initialize Test twice. Because each time a class load, it loads with its all child. So whenever Test2 class loads it loads and initialize the Test outside and inside of constructor.

That is why you are getting Constructor called 1 also.

Comments

0

You get those output because the order of execution goes like this:

class Test2{
    Test t1 = new Test1(1);     //Executed first

    public Test2(int i){
        t1 = new Test(i);    //Executed second    
    }
}

The next thing you need to know is constructor will be invoked when you use the new keyword. Hence the constructor in class Test1 is invoked 4 times:

public static void main(String[] args) {    
     Test2 t2 = new Test2(5);    //Test1 constructor invoked twice here
     Test2 t3 = new Test2(15);   //Test1 constructor invoked twice here
}

Running Test2 t2 = new Test2(5); will invoke

new Test1(1);    //from: Test t1 = new Test1(1);
new Test(5);     //from: t1 = new Test(i);

Running Test2 t3 = new Test2(15); will invoke

new Test1(1);    //from: Test t1 = new Test1(1);
new Test(15);    //from: t1 = new Test(i);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.