About Question enthuware.ocajp.i.v7.2.1337 :

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

That is just the way the language is designed to work. It may look weird but there is nothing special going on there to understand.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

AristPhil
Posts: 4
Joined: Wed Jan 06, 2016 5:38 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by AristPhil »

Can I explain the reason, why the value 4 has not been assigned to variable i when the superconstructor calls the overridden print() method, like this?
I. All instance variables are initialized with their default values when their class is loaded. Thus, i is initialized with 0, when class B is loaded.
II. The actual initialization with concrete values happens in this order:

1. all static initializer blocks and static variables are initialized down the class hierarchy, i.e. from the uppermost superclass first down to the calling subclass last - in our mock question there are no static block or variable at all;

2. all instance initializer blocks and instance variables of the uppermost superclass are initialized (in whatever order they appear in the code) - in our mock question we don't have such.

3. the constructor of the uppermost superclass is initialized - in our mock question this is class' A no-arg constructor that calls the overridden print() method of (sub)class B:
Since class' B instance variables have only been assigned to default values so far (here i=0;), 0 is printed to the console. This is, why we see 0 instead of 4!

4. all instance initializer blocks and instance variables of the second uppermost superclass are initialized - as in our mock question there is only one superclass A, we've just arrive at our base class B: NOW i is set to 4 - but not printed out yet!

5. the constructor of the second uppermost superclass is initialized - again we arrive at the base class B and its default constructor. NOW main() calls the overridden print() method which prints 4 to the console.

Summary: As step 4 has not run by the time the superconstructor calls the overridden print() method, which at this point can only return the default value of 0 for variable i, we get an console output of 0 4 instead of 4 4.

Step 1 is executed first upon class loading for all classes. After that the instance initialization and constructor execution is done together per class down the class hierarchy - (NOT instance initialization of all classes followed by constructor execution of all classes)! This is why i has not been set to 4 but is still 0 when the superconstructor calls the overridden print() method.

(For simplicity, I omitted the exact execution flow due to constructor chaining; it does not matter here).

P.S. Luckily I found a good example in the JSL: http://docs.oracle.com/javase/specs/jls ... l#jls-12.5 (Example 12.5-1. Evaluation of Instance Creation); explained in lucid terms!
Last edited by AristPhil on Fri Jan 15, 2016 10:17 am, edited 1 time in total.

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

AristPhil wrote:Can I explain the reason, why the value 4 has not been assigned to variable i when the superconstructor calls the overridden print() method, like this?
...
You got it :)
If you like our products and services, please help us by posting your review here.

eddie3
Posts: 14
Joined: Sat Dec 17, 2016 10:17 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by eddie3 »

Shouldn't the code prints 0, 4, 4? There is no constructor in class B, so a default constructor that calls super( ) is automatically inserted in class B. Therefore, when A a = new B( ); is executed, first Java calls the no-arg constructor in A (which prints 0), then calls the automatically inserted no-arg constructor in B(which prints 4 because a constructor is the last step of all initialization process). And at last a.print( ) will print 4. So the code will print 0,4,4?

To test it out, I compiled a simplified code in Java,

Code: Select all

class A{
    public A(){System.out.println("A");}
}

class B extends A{
    public B(){System.out.println("B");}

    public static void main(String[] args){
    A object = new B();
    }
}
And it prints

Code: Select all

A
B

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

Not sure what you mean by the bold part in, "...then calls the automatically inserted no-arg constructor in B (which prints 4 because a constructor is the last step of all initialization process). Why do you think the default constructor that is automatically inserted will have a print statement in it?
Paul.
If you like our products and services, please help us by posting your review here.

eddie3
Posts: 14
Joined: Sat Dec 17, 2016 10:17 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by eddie3 »

Because the default constructor in class B will call the super( ) as its first statement, and in the case of this question, since A is the super class of B, shouldn't the the no-argument constructor in class A, which contains the body, {print( )}, be called?

Also, what I mean in the bold line is that when a class is initialized, the static fields and block will run first, then instance fields and blocks, and at last the constructor. Therefore, int i will have already been given a value of 4 before the default constructor in class B is called. And the default constructor in class B call super( ), which calls the overriding print( ) method in class B, and prints out i, which is 4.

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

Your post tells me that you have not fully understood the flow of execution of constructors and initializers. When you do new B(), the default constructor of B is invoked, which, in turn calls super(). Now, in the given code, class B does not have an explicitly defined constructor. The default one that is provided by the compiler only contains a call to super(). It does not contain any print statements. Therefore, when the call to super() executes, A's constructor will be invoked, which contains a call to print(i). This call will print 0 at this time because i hasn't yet been assigned the value of 4. Execution control will then return back to the default constructor of B, which has no further statements.
Finally, the line a.print() from main will be executed, which will print 4 because by this time i has been initialized to 4.

That's it. There is no third print statement anywhere.

I will suggest you to read about this from a book or try running various code variations.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

eddie3
Posts: 14
Joined: Sat Dec 17, 2016 10:17 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by eddie3 »

Oh, I get it now. So this line "A a = new B( );" will actually call B's no-argument constructor instead of A's. I misunderstood because of this sentence in the explanation: "Here,when an object of class B is created, first A's constructor is called." I thought this means that "A a= new B( );" will call A's constructor instead of B's. Now I understand that this will actually call B's constructor, but in the case of this question calling B's constructor is calling A's constructor, because of the lack of an explicit constructor in B's. Thank you for the clarification!

dxie1154
Posts: 9
Joined: Sat Jan 14, 2017 5:01 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by dxie1154 »

Hi,

I don't really understand the part on how B's print() method is executed.
From how I saw it, I had thought that it would call A's print() because it is in the A class, and the constructor that calls the print() method is in the A class as well.
But now it says it will call B's print() so I am really confused on this.
Can you tell me why it will call B's print()?

Thanks in advance.

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

Note that print is a non-private instance method and is therefore polymorphic, which means, the selection of the method to be executed depends on the class of actual object on which it is invoked. Here, since the class of actual object is B, B's print is selected instead of A's print.
If you like our products and services, please help us by posting your review here.

Chandu
Posts: 7
Joined: Thu Mar 30, 2017 7:15 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by Chandu »

Code: Select all

class A{
   A() {  print();   }
   void print() { System.out.println("A"); }
}
class B extends A{
   int i =   4;
   public static void main(String[] args){
      A a = new B();
      a.print();
   }
   void print() { System.out.println(i); }
}
What will be the output when class B is run ?

Explanation: Note that method print() is overridden in class B. Due to polymorphism, the method to be executed is selected depending on the class of the actual object. Here, when an object of class B is created, first B's default constructor (which is not visible in the code but is automatically provided by the compiler because B does not define any constructor explicitly) is called. The first line of this constructor is a call to super(), which invokes A's constructor. A's constructor in turn calls print(). Now, print is a non-private instance method and is therefore polymorphic, which means, the selection of the method to be executed depends on the class of actual object on which it is invoked. Here, since the class of actual object is B, B's print is selected instead of A's print. At this point of time, variable i has not been initialized (because we are still in the middle of initializing A), so its default value i.e. 0 is printed.   Finally, 4 is printed. 
Query-------------// in this i got a doubt that if value of "i" isnt initialized at that point of time then how come its assigning the default int value for that variable? i mean if the control doesnt go to that line of code during that particular time of execution then how come compiler knows the data type of that variable and assigns the default value for it?

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

1. This is about execution. There is no compiler involved in execution. It is the JVM.
2. When an object is created, the first thing JVM does is allocate space for that object. This space includes space for its instance variables. This space that is used for instance variables is all filled with zeros. This is the default value of all kinds of variables. If the variable is a primitive it is 0, if it is a boolean the value is interpreted as false, and if the variable is a reference variable, it is interpreted as null.
3. After the JVM allocates space for an object, it executes the initializers, and constructors.

The value that is being talked about in this question is the value that is there in that space after memory allocation and before execution of any initializers/constructors.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

shambhavi
Posts: 25
Joined: Fri Aug 04, 2017 12:21 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by shambhavi »

gustavomzina wrote:I understand that instance members are initialized after the super() method call within B class constructor. But why does the code below outputs 4, 4?

Code: Select all

class A{
	A() {  print();   }
	void print() { System.out.println("A"); }
}
public class B extends A{
	final int i =   4;
	public static void main(String[] args){
		A a = new Teste();
		a.print();
	}
	void print() { System.out.println(i); }
}
Final members are not instance members?

Thanks.
Final fields are instance members but they are not always given a default value ! try it out as illustrated in the explanations below !
int i; will compile but
final int i; // will not compile if you haven't initialized it anywhere in the constructor too

since in your code you have given final int i=4; this is a compile time constant whose value is known at compile time itself and hence, when this variable is created at run time it will be assigned this value itself rather than a default value because anyways its a constant and its value will not change in the rest of the program !

but observe in the below code : output is :
0
4

Code: Select all

class A{
	A() {  print();   }
	void print() { System.out.println("A"); }
}
 public class B extends A {
    
final int i;
B()
{
    i=4;
}

   void print() { System.out.println(i); } 
     
           
  public static void main(String[] args) { 
    
  A a = new B();
		a.print();
 
      System.out.println();
      
      
 }
 }
here a default value is given since its value is not known at compile time and 4 is assigned only after its first useage !

Angi000
Posts: 3
Joined: Sun Jan 28, 2018 12:44 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by Angi000 »

Hi Paul,

I don't understand why the default value of 'i' is used when creating the object 'a' is referring to. So 0, not 4. Please help.

Thanks

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

When you do new B(), the JVM has to initialize the memory space for an object of class B. Included in B are the instance fields defined in A as well. So when the JVM tries to initialize B, it has to first initialize the instance members of A. While initializing the fields of A, the JVM encounters a print statement that tries to print the value of i. But at this time, i has not been initialized fully (because B's constructor hasn't run yet), so the print statement prints the default value assigned by the JVM i.e. 0.
If you like our products and services, please help us by posting your review here.

ArpRokz
Posts: 15
Joined: Sun Jan 28, 2018 12:38 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by ArpRokz »

I understood this in the following way..

When we call print() from within class A's constructor it is like calling this.print(). Here "this" refers to the currently calling object. Since the actual object used was of class B therefore class B's print() is called. Now since class B's constructor requires a call to class A constructor first so i=4 is not executed till now therefore 0 is printed.

Is this explanation correct or am I wrong ?

elias86
Posts: 7
Joined: Fri May 04, 2018 4:14 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by elias86 »

Why is printed 0 instead of A???

When I call the B constructor (which is a default constructor because it's not declared) java calls the super-constructor (A constructor) so it calls print method (of the B class). This method calls print() method that prints i. So if i == 4 why it prints 0?

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

Please go through the discussion above.
If you like our products and services, please help us by posting your review here.

crazymind
Posts: 85
Joined: Mon Dec 24, 2018 6:24 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by crazymind »

Hi, I read your explanation of this question; However, there is one thing still confuse me. According to order of initialization, the instance variable initializes before the constructor call. So before calls A(), 'i' is initialized to 4 already. Why is it 0? thanks

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

Please go through the discussion above.
If you like our products and services, please help us by posting your review here.

Denyo1986
Posts: 38
Joined: Thu Jan 07, 2021 2:47 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by Denyo1986 »

I dont mean to be a smart-ass but since in other questions it was more precise and especially since there is a "none of the above"-option, I would suggest to remove the comma from the response options, as there is no piece of code printing any comma. The correct output would be 0 4.

Great question by the way. I would never have imagined in my wildest dreams that A calls the overridden method. I would have thought it always calls its own method. This is crazy....

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

Good point. Done.
thank you for your feedback!
If you like our products and services, please help us by posting your review here.

fortesp
Posts: 9
Joined: Mon Dec 14, 2020 8:53 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by fortesp »

Shouldn't this be "None of the above"? The result after executing the code is 04 and not 0 4.

admin
Site Admin
Posts: 10053
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1337 :

Post by admin »

You are right. Updated System.out.print(i); to System.out.print(i+" ");
thank you for your feedback!
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: No registered users and 48 guests