wood burning stoves*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes JQuest question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "JQuest question" Watch "JQuest question" New topic
Author

JQuest question

Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133

The above code prints out 0 instead of 10. Can someone tell me why giveMe returns j as 0 instead of 10?


Sun Certified Java Programmer
Deepak Jindal
Ranch Hand

Joined: Nov 16, 2000
Posts: 30
I guess at the time of initialization of i, it gives a call to function giveMe(). And since j has not been initialized any value, it returns 0.
Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133
Actually j was not even declared when we call giveMe(). The following code will give forward referencing error. But why the original code compiles fine. It seems to me when giveMe() was called, the compile reads int j, but ignores its assigment. This seems a little weird.
Pravin Panicker
Ranch Hand

Joined: Oct 05, 2000
Posts: 62
Hi Tom,
Interesting Question.
Lets proceed according to the order of initialization :
1* Initially instance variables are initialized
so i = giveMe();
now control goes to giveMe
since j is not initialized as yet
it is initialized to 0
and so i=0.
2* now j = 10
the result would have been different had you written
int j= 10;
int i= giveMe();
This would have printed 10.
BottomLine : The order of initialization is important!
Regards
-- Pravin Panicker


Pravin R Panicker<br />SCJP,SCWCD
Golam Newaz
Ranch Hand

Joined: Jan 08, 2001
Posts: 64
Hi,
Pravin saying that order of initialization is important. Look
i just changed line no. 3. Just put final ie makes it constant.
And it gives the output of value 10 not 0. Look the assigning
value of j into i works perfectly. In this case should i
have to follow order of initialization or the others thing.
So it has been proved that method calling and the variables are
strongly related with other like final and static keyword.

public class Test { // Line 1

private int i=giveMe(); // Line 2
private final int j=10; // Line 3
public int giveMe(){ // Line 4
return j; // Line 5
} // Line 6
public static void main(String args[]){
System.out.println((new Test()).i);
}
}
Really weird also to me.
- Golam Newaz
Wong KK
Ranch Hand

Joined: Jan 15, 2001
Posts: 52
Because j is final, method giveMe has been changed in compile time as follows:
<code>
public int giveMe(){ // Line 4
return 10; // Line 5
} // Line 6
</code>
The order of declaration is still necessary but now variable i can get 10 at run time.
Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133
Thanks guys. I think we can analyze this problem in two parts. Compiling time and run time.

At compile time, the above code won't cause forward referencing error because the compiler goes line by line. When it read line two, it knows j was declared and had a default value of 0. (the explicit initialization will happen at runtime) So at line 5, the compiler will read as return 0.
At runtime, the control will jump from line 1 to line3-5 and return to line1, therefore i is initialized as 0 and hence the output.
In case of fina int j=10, the compiler will remember j as 10 instead of the default 0 because it's a constant. And therefore the output is 10.
I think this explains everything. Compiling order and initialization order at runtime seem to be two different concepts. Correct me if I'm wrong.
[This message has been edited by Tom Tang (edited February 07, 2001).]
Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133
Sun's tech tip has an excellent explanation of a similar question:

The output of the program is:
0
37
You might expect the two values in the output, bobj.a and bobj.f(), to match.
But as you can see they don't. This is true even though a is initialized from
B's f method, and the values of a and B's f method are printed.
The issue here is that when a is initialized by the call to B's f method, and
the method returns the value of the b field, that field value has not been
initialized yet. Because of that, the field has the value given to it by default
initialization, that is, 0.
These examples illustrate an important programming point -- it's usually
unwise to invoke overridable methods during the construction phase of an
object.
Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133
The above comes from the following link; http://developer.java.sun.com/developer/TechTips/2000/tt1205.html#tip2
It also has some other good example similar to those in Khalid mock exam qustions.
Cherry Mathew
Ranch Hand

Joined: Dec 26, 2000
Posts: 159
Newaz,
It was a good one i never thought final will have such effect in this particular case.
Tom as usual u ask questions and u give good explanations also.
Tom when are u planing to give the exam(or did u give ) im planning to give on 19 th of Feb.
All the best
Cherry
Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133
Dear Cherry:
Thank you for the kind encouragement. I will take the test on Feb.28. And I wish you good luck first. Do come back and share your experience. I believe you have no problem passing it. It's just a question of how high you can go.
Tom
praveen ankireddy
Greenhorn

Joined: Feb 07, 2001
Posts: 22
hai,
As soon as i is initialized the function giveme()
is invoked which doesnt have the value of j and the class variable is automatically intilized to 0 thats the reason 0 is printed else u try out placing the statment j=10 as the first statement u will get the result as desired
Regards
Praveen ankireddy


P Ankireddy
deep_scjp
Greenhorn

Joined: Jan 04, 2001
Posts: 12
hi guys
cool it
take the original code and 4get all the reeplies to it for the time being
the JRE parses the .class file many times
in the first few parses creation of the base class Object etc take place by default
now when it comes to creating the object of this class
all the declarations undergo the 1st pass
in this he finds the declarations
int i
int j
public giveMe()
there r 3 memory locations initialized now
each of 32 bits
1st for variable i
2nd for variable j
3rd for giveMe()
remember JRE does not look for the assigment / defining the variables in this parse .... it only declares them n initializes the chunks of memory to them.
But at the same time JRE assigns a default value to the variable
which is 0 in case of int
so now
1st int i=0
2nd int j=0
now in second parse JRE defines/ assigns the variables the given values
so now at this parse JRE 1st finds the assignment to i which is
( unfortunately ) a function named giveMe()
now giveMe prints called and then returns j
and right now j is assigned 0 by default coz JRE has not yet reached the j's definition which j = 10;
so this function returns 0 and assigns it to i
then JRE proceeds to the next line n finds definition of j and assigns the value 10 to j
this is how the o/p of the code is 0

now the next query about the final keyword
here at the first parse itself JRE finds the declaration
final int j = 10;
now final tells JRE that this variable not only has to be initialized with memory but also has to define/assign the value 10 to it coz this value can never be changed later
therefore when u put final j is given its 32 bits n also assigned to 10 immediately on the 1st parse itself
now on the second parse JRE finds giveMe()
n it returns 10 this time which is assigned to i
so the code with final prints 10
bye
Deepak
Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133
Hi, all:
If you really want to go deep into the compiling process. Please execute from the current directory: javap -c Test
You will know exactly what's happening behind.
Tom
Charlie Swanson
Ranch Hand

Joined: Jan 29, 2001
Posts: 213
I ran the code with javap -c Test. The output is below. Can someone please explain how it explains what is happening in this case.
Compiled from test.java
public class test extends java.lang.Object {
public test();
public static void main(java.lang.String[]);
}
Method test()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 aload_0
5 aload_0
6 invokespecial #2 <Method int giveMe()>
9 putfield #3 <Field int i>
12 aload_0
13 bipush 10
15 putfield #4 <Field int j>
18 return
Method int giveMe()
0 aload_0
1 getfield #4 <Field int j>
4 ireturn
Method void main(java.lang.String[])
0 getstatic #5 <Field java.io.PrintStream out>
3 new #6 <Class test>
6 dup
7 invokespecial #7 <Method test()>
10 getfield #3 <Field int i>
13 invokevirtual #8 <Method void println(int)>
16 return
Charlie Swanson
Ranch Hand

Joined: Jan 29, 2001
Posts: 213
I ran the following code:
public class test {
private int i= giveMe();
private int j=10;
private int giveMe(){
System.out.println("give me " + j);
return j;}
public static void main(String args[]){
System.out.println("before calling anything");
test t1 = new test();
System.out.println("after init test");
System.out.println("main called give me " + t1.giveMe());

}
}

The output was:
before calling anything
give me 0 //created when constructor is called
after init test
give me 10 //called when method was called
main called give me 10 //called when method was called
Cherry Mathew
Ranch Hand

Joined: Dec 26, 2000
Posts: 159
hi Tom,
now that u have given the code please explain it
i just know these are internal calls
Cherry
Tom Tang
Ranch Hand

Joined: Dec 24, 2000
Posts: 133
Charlie and Cherry:
I hope I didn't open the Pandora's box.
The byte codes in the class file are for advanced programmers. I'm sorry to say I can't explain them all. If you are interested, please refer the following link. It has some discussion about those machine codes.
http://developer.java.sun.com/developer/TechTips/2000/tt1205.html#tip2
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JQuest question
 
Similar Threads
A basic question..
Forward Referencing
forward referencing
Method invoke
Forward Referencing to method