aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes what is it after all Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "what is it after all" Watch "what is it after all" New topic
Author

what is it after all

Mateen Nasir
Ranch Hand

Joined: Aug 01, 2001
Posts: 33
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

Joined: Apr 14, 2001
Posts: 327


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

Joined: Sep 27, 2001
Posts: 53
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

Joined: May 10, 2001
Posts: 3244
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


Dave
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
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.


SCJP2. Please Indent your code using UBB Code
Mateen Nasir
Ranch Hand

Joined: Aug 01, 2001
Posts: 33
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

Joined: Jul 03, 2001
Posts: 2120
JLS 15.8.3:
"The type of this is the class C within which the keyword this occurs. "
 
jQuery in Action, 2nd edition
 
subject: what is it after all