• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

what is it after all

 
Mateen Nasir
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
a ques from jtips
class Process {
byte b=127;
Process() {
this.methodA();
}
void methodA() {
System.out.println("Value of b is = " + b );
}
public static void main(String [] args) {
Processor p = new Processor();
}
}
class Processor extends Process {
byte b=126;
Processor() {
System.out.println("Value of b = " + b);
}
void methodA() {
System.out.println("Value of b = " + this.b);
}
}
What is the Output?
1.Prints Value of b = 0 and Value of b is = 126.
2.Compile-time error occurs.
3.Prints Value of b = 126 and Value of b = 126.
4.Prints Value of b = 127 and Value of b = 126.

the answer gives is 1
i have run this and its the correct answer
but why/?
why is it not 4
first the parent cons is called and the value is 127
then child where value is 126
why a 0 printed
i cant get it !!
 
Angela Narain
Ranch Hand
Posts: 327
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


To solve , lets us follow the the below steps
( I am marked the below steps in the code for reference )
1. In the main() method , we execute Processor p=new Processor().
2. So this will first give a call to default constructor of
super class. that is Process()
3. As an object of Processor() has been already created as in step 1.
the "this" refers to the Processor object.
So the methodA() of the Processor class is called //3
4. At this time none of the varaibles has been initialized ,
they are having their default value, so byte b=0 in the
Processor class.
Thus methodA() will print the value of b as 0 //4
5. Now after we have finished with the constructor of the super
class Process we now come to the subclass Processor.
This time we initialize the class , specifically the variables
so byte b = 126 gets executed //5
6. After this we continue with the Processor() default constructor
This time printing the value of b will be 126 //6

Anyone can correct if i have missed anything.
 
Bill Krieger
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay. Events occur in the following order when you hit the line
"Processor p = new Processor();" in your main function.
First the Processor() constructor is invoked. The first thing it does is invoke it's parent constructor. That means we next go into the Process() constructor. The first thing it does is invoke it's parent constructor, i.e. Object(). We can ignore the Object constructor since it has no visible effect on what transpires.
In the constructor, since this is the first element of this class encountered, we need to do static initialization. (I know I'm really talking about class loading, but this still describes the order of what happens.) First Process() (base class) static initialization is done, then Processor (derived class) static initialization is done. In your example, there is no static initization, but it's important to know that class Processor (derived class) static initialzation is done before Process (base class) object (instance) variable initialization is done.
Next, we do the non-static part of the base class (Process) constructor, including the initialization of instance variables. First, we set the local (Process) variable b to a value of 127. Then we call this.methodA(). Note that "this" is really a "Processor" (derived class) reference, not a "Process" (base class) reference. Therefore, due to polymorphism, we actually invoke the "Processor" (derived class) version of methodA().
Inside the Processor methodA() method, the value of b is printed. In Processor methodA(), "this" is considered a reference to a Processor (derived class) object. Therefore, it's the Processor version of value b that gets printed. Note that there hasn't been any initialization yet in the Processor (derived) class. Therefore, the value that gets printed is zero.
Next, we return from Processor.methodA() back to the Process (base class) constructor. Here there's nothing more to do, so we exit back to the Processor (derived class) constructor.
Now that we're back in the derived class, we do all the local instance initialization. That is, we set the value of b to 126. Note how this occurs after the base class constructor has already printed out it's value via a call to method methodA().
Finally, we execute the statment[s] in the constructor, which prints out the just initialized value of b, which is 126.
The point of this question is that the entire base class constructor is executed before any part of the derived class constructor. That includes object (instance) variable initialization. The not yet itinialized instance variables in in the derived class can be accessed and manipulated from within the base class constructor via overridden method calls (polymorphism).
You know, I think I answered this question once before, too. Oh well.
Bill
 
Dave Vick
Ranch Hand
Posts: 3244
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mateen
The call to methodA in the constructor for Process calls the methodA in the Processor class because it is overridden. So when it is called the value of b has not been assigned yet (because no processor object has been created) so it has the default value of 0.
Then in the constructor for Processsor just before it calls methodA (again it is the Processor version) all of the instance initializers have been run so the variable b has been initalized in the Processor class to its value of 126 so that is what is printed.
For a detailed explaination of the steps check out the JLS section 12.5
hope that helps

------------------
Dave
Sun Certified Programmer for the Java� 2 Platform
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In fact, for any constructor not starting with a this(...) invocation, the compiler places the code that initializes the instance fields between the super invoaction (explicit or implicit) and the rest of the code in the constructor.
javap -c className shows it.
I think the example shows the reason we shouln't invoke polymorphic methods in a constructor. Some fields of the object could be accessed before proper initialization.
 
Mateen Nasir
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
firstly thanks for the great explinations
now !!
we all know that varibales are accessed by reference type and not object type
so if i change this to
Process p = new Processor() ;
now when it runs then inside the child method this.b should
refer to the parent's variable because that is the process
reference type. but it still gets the same error
i hope u get it
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
JLS 15.8.3:
"The type of this is the class C within which the keyword this occurs. "
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic