• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Question #9 from Doug's book

 
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Take a look at this code and give an opinion as to whther it will compile and as to what it will print if it does compile.
 
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Thomas, my first guess of printing zero happened to be correct (no, honestly, I ran it afterwards )
It's a good question on how the compiler does linking and how JVM resolves assignments at runtime. Correct me if I'm wrong. Could you explain what actually happens in the code?
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The member variable initializations are executed immediately before the body of whatever actual constructor is invoked , in the order that they appear. When forwardReference() is called, i is set to 100, then when it returns, j is set to 100 as well. Next, i is initialized to 0. Then, the no-argument, empty, default constructor is executed, which changes nothing. Finally, the value of i from the fully-constructed object is read, and its final value is 0.
So i's value is changed twice during Test construction!
 
Vad Fogel
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A pretty exhaustive explanation Ernest, thanks. Should we expect any questions like this one on the exam?
 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
HI,
In this case when the call to forwardReference() method is made, the compiler still doesnt know anything about the variable i, so if we use that variable in this method, the compiler should complain.. but it doesnt.. may i know why?
Thanks in advance
Regards,
Harry
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The first thing that happens is that all fields are allocated and set to their initial values. So before forwardReference() runs, i has been created and set to the default value of 0. Then we update i but then i gets the value of zero assigned to it.
You can play around with this a little bit. Try changing,
int i = 0;
to
int i = 5;
The main idea behind this code is that fields always get assigned the initial value you assign to them even when the initial value you assign to them is the same as the default value.
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Harjinder,
from
JLS 8.3.2.3 I concluded that the restrictions on the access to fields during initialization are not applied to methods.
______________________________________________________________________
Ernest,
a minor slip : the (default) constructor is executed before the field initializers, and before the constructor body. I know you knew it.
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi
my understanding is the order of execution starts from main
hence in the following code the execution from line 8 moves to line 2 and then to line 4
So if i'm correct the compiler must complain as it doesnt know anything about the variable i :roll:
pl correct me if i'm wrong

Thanx in advance
 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
tangi,
As you stated, the execution will start from line # 8, but the next step is not line # 2. It is default constructor. Before the default constructor's block completes, the instance variables will be initialed. But these instance variables will be assigned to their default values, as soon as the flow goes into the default constructor. Hence there is no question that the compiler does not know i. Hope I am clear.

Suggestion: Your display name is not as per the rules of JavaRanch.
Reddy
 
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jose
Jose : Ernest,
a minor slip : the (default) constructor is executed before the field initializers, and before the constructor body. I know you knew it.

I guess that you mean to say that before instance member intialization the constructor runs. But I guess what Ernest is saying is actually what happens.
Try this code
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Anupam,
Yes I see my sentence is not clear . I mean the default constructor is called before the initialization of the instance fields. Then "super()", the first sentence in the constructor is invoked. After that the initialization of instance fields, and at last the body of the constructor are executed.
__________________________________________________________________________

Welcome to the Ranch tangi.
JLS 8.3.2.3 says that methods are not checked for forwarding referecences on fields. Also notice that in "return i=100;" the access to "i" occurs in the left hand side of an assignment. Thus the compiler should not complain even if the expression were placed in an instance field initialization code:

[ August 30, 2003: Message edited by: Jose Botella ]
 
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
May I please know what the output of the above mentioned code is? When I compiled it I got an output of : 100
 
Anupam Sinha
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jose Botella:
[QB]
Welcome to the Ranch tangi.
JLS 8.3.2.3 says that methods are not checked for forwarding referecences on fields. Also notice that in "return i=100;" the access to "i" occurs in the left hand side of an assignment. Thus the compiler should not complain even if the expression were placed in an instance field initialization code:


My compiler is not at all happy.

I guess your shouldn't also be happy because you are intializing i before declaring it.
[ August 30, 2003: Message edited by: Anupam Sinha ]
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is the happy compiler:
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)
And this is what makes the compiler happy:


8.3.2.3 Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
* The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
* The usage is not on the left hand side of an assignment.
* C is the innermost class or interface enclosing the usage.


Replacing the sentence with "int j = i ;" will cause an "illegal forward reference" compiler error.
You might be tempted to think that "i" in "int j = i = forwardReference();" is to the right of "int j =", however JLS 15.26 says:


There are 12 assignment operators; all are syntactically right-associative (they group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to b and then assigns the value of b to a.
.
.
.
At run time, the result of the assignment expression is the value of the variable after the assignment has occurred. The result of an assignment expression is not itself a variable.

 
Anupam Sinha
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mine is

and it says
 
Anupam Sinha
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jose
You are correct.
It's a bug. Follow this link.
I couldn't see the full text, can anyone can?
Jose in an earlier post I read that the output is 100 is it true. I don't have a 1.4.2 complier to check it. Please someone verify the output.
[ August 30, 2003: Message edited by: Anupam Sinha ]
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The correct output is 0. This was corrected in the 1.4.2 compiler.
[ August 30, 2003: Message edited by: Thomas Paul ]
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now why the code that initializes fields has restrictions on forward references towards fields, but the code within a method hasn't got them?
The code that initializes fields is executed in textual order(*). However there is not such relationship between the code that initializes fields and the one inside methods.
(*) instance and static fields are not mixed here
 
Harry Singh
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
HI All,
So going by this disciussion, the steps that compiler actually performs are :
1. The main() method is searched and compiler starts executing the main method.
2. Compiler goes in to the default constructor or constructor explicitly defined.
3. A call to super () or this() is then made from the constructor.
4. Then all the field initializations takes place in the order in which they are defined in the code.
5. then the body of the constructor in executed.
6. control falls to next line in main() method.
Apart from this, if we use methods in instance initialization code, the complier will be happy as complier doesnt check for forward referencing in case of methods.
Please correct me if i am wrong.
Regards,
Harjinder
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic