wood burning stoves*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Why this(a) be rejected by compiler? 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 "Why this(a) be rejected by compiler?" Watch "Why this(a) be rejected by compiler?" New topic
Author

Why this(a) be rejected by compiler?

James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186

Why this(a) be rejected by compiler?
I think "a" has been initialized here and has a default value 0 and is legal for use.
Could anyone tell where in the JLS can i find the related rules against such reference.
Thanks in advance
James
shadow liu
Ranch Hand

Joined: Mar 19, 2001
Posts: 33
As I remember, the calling sequence is below:
1) if there are super or this call in constructor, do it.
2) call superclass (till Object) constructor
3) then the initial part the class
4) the rest of the class constructor.
so this(a) is exec in 1)
but 'int a' initial will be exec in 3).
HTH.
Scott Appleton
Ranch Hand

Joined: May 07, 2001
Posts: 195
Of course, if you make the variable a static, it will be initialized when the class loads and will be available when the constructor is called.
Ravindra Mohan
Ranch Hand

Joined: Mar 16, 2001
Posts: 216
Hi Shadow,
You have hit the bulls eye, bingo! But only that you missed out
was that the first things that loaded is the static initialisers
and static blocks in the order they appear in the class.
Hope this clarifies.
Ravindra Mohan.
vivek bawge
Greenhorn

Joined: Apr 19, 2001
Posts: 24
Originally posted by shadow liu:
As I remember, the calling sequence is below:
1) if there are super or this call in constructor, do it.
2) call superclass (till Object) constructor
3) then the initial part the class
4) the rest of the class constructor.
so this(a) is exec in 1)
but 'int a' initial will be exec in 3).
HTH.


As per your sequence what should be the output of the following code
class Base
{
public void amethod()
{
System.out.println("Base.amethod()");
}
Base()
{
amethod();
}
}
public class Derived extends Base
{
int i = 10;

public static void main(String argv[])
{
Base b = new Derived();

}

public void amethod()
{
System.out.println("Derived.amethod() " + "Value of i is" + i);
}
}
As unexpected, the output is Derived.amethod() Value of i is 0.
As per your sequence, should it give a compile time error because the i in derived is not initialized when the base class constructor calls it.
Thanks,
Vivek
Cindy Glass
"The Hood"
Sheriff

Joined: Sep 29, 2000
Posts: 8521

This is the actual JLS wording

12.5 Creation of New Class Instances
.
.
.
.
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:

1) Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
2) If this constructor begins with an explicit constructor invocation of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
3) This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
4) Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5. (In some early implementations, the compiler incorrectly omitted the code to initialize a field if the field initializer expression was a constant expression whose value was equal to the default initialization value for its type.)
5) Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally. In the example:


"JavaRanch, where the deer and the Certified play" - David O'Meara
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186
Hi Cindy, what's your viewpoint directly?
That's what i found in JLS just precede the quotation you cited above.

Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden (��8.3). If there is not sufficient space available to allocate memory for the object, then creation of the class instance completes abruptly with an OutOfMemoryError. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values (��4.5.5).

According to this,before all the 5 steps executed, all the instance variables already have their default values!
I think vivek's code have exhibited and proved that.
Then, Why this(a) is rejected by the compiler?
Regards,
James
[This message has been edited by James Du (edited May 08, 2001).]
Jane Griscti
Ranch Hand

Joined: Aug 30, 2000
Posts: 3141
Hi James,
See JLS§8.8.5.1 Explicit Constructor Invocations

An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.
For example, if the first constructor of ColoredPoint in the example above were changed to:
ColoredPoint(int x, int y) {
this(x, y, color);
}
then a compile-time error would occur, because an instance variable cannot be used within a superclass constructor invocation.

Hope that helps.
------------------
Jane Griscti
Sun Certified Programmer for the Java� 2 Platform


Jane Griscti
SCJP, Co-author Mike Meyers' Java 2 Certification Passport
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186
Hi Jane, you get the point again, thanks.
But I still dont quite understand the reason it states:
because an instance variable cannot be used within a superclass constructor invocation.
I think this(a) has nothing to do with superclass constructor invocation! Furthermore, all the arguments are evaluated and passed to the fomal paremeters before the code in the called method(or constructor) execute, say, even through you called super(a), it could be interpreted to super(0), there's no chance that the code in the superclass constructor reference the subclass field a.
Regards
James
shadow liu
Ranch Hand

Joined: Mar 19, 2001
Posts: 33
Hi, Vivek, your example is a little complex since it use override. I think the 'i' is print out as 0 is really a little confused though it works in fact.
see the revised code

The output is
Derived.amethod() Value of i is0
Before i
After i 10
So, 'Before i' is printed after the Derived.amethod(), but actually, 'Before i' can not use 'i'. uncomment that line to see the compile error.
It seems that some method called in constructor CAN use the var (value is the default init value), but the init block still CAN NOT use the var, until it is explicit initialized.
Sorry, Maybe a little out of topic.

[This message has been edited by shadow liu (edited May 09, 2001).]
Jane Griscti
Ranch Hand

Joined: Aug 30, 2000
Posts: 3141
Hi James,
Ctor's are handled much like methods; parameters are evaluated first. When you use an explicit call ie this(a), another ctor for the same class is invoked after the parameter 'a' is evaluated. At this point, neither the class nor it's superclass has been created and no instance variables exist.
Whenever a class is instantiated, all of it's superclasses are created first. This can happens explicitly ie with a call to super() or implicitly; but it must occur if a method or ctor is called.
Hope that helps.
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186

originally posted by Jane
When you use an explicit call ie this(a), another ctor for the same class is invoked after the parameter 'a' is evaluated. At this point, neither the class nor it's superclass has been created and no instance variables exist.

Hi Jane, that's what I found in jls:

Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden (��8.3). If there is not sufficient space available to allocate memory for the object, then creation of the class instance completes abruptly with an OutOfMemoryError. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values (��4.5.5).

That step is said what JVM do before all other 5 steps when a new class instance is created.I think there's some inconsistence here.
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186
By the way, Jane, could you please give a look at my other question titled "regarding blank final ".
I think these 2 questions have some points common.
Thanks
James
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186
Hi java gurus, pls. don't let my question drowned without sound!
Trust me, it worth the effort.
Jane Griscti
Ranch Hand

Joined: Aug 30, 2000
Posts: 3141
Hi James,
The fact that memory has been allocated and the instance variables have been set to their default values is not taken into account by the compiler. The rule is "An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs." (JLS 8.8.5.1)
It may sound like a lame answer, and the JLS may contradict itself, but the bottom line is .. it won't work. Why? I'm not sure; other than to say that's the way it was designed.

------------------
Jane Griscti
Sun Certified Programmer for the Java� 2 Platform
Madhu SK
Greenhorn

Joined: May 07, 2001
Posts: 12
Originally posted by James Du:
[B]
Why this(a) be rejected by compiler?
I think "a" has been initialized here and has a default value 0 and is legal for use.
Could anyone tell where in the JLS can i find the related rules against such reference.
Thanks in advance
James[/B]

----------------------------------------------------
I am a little confused here. "a" will be initialized and has a default value of zero ONLY after the class's constructor call has been completed. Right? Please explain
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186
Finally there's response again, thanks.

originally posted by Madhu
I am a little confused here. "a" will be initialized and has a default value of zero ONLY after the class's constructor call has been completed. Right? Please explain

Hi, Madhu, if you would read the preceding posts carefully, you could get it.There's another question titled "regarding blank final", I quoted some states from jls, maybe helpful to you.
Regards,
James
 
jQuery in Action, 2nd edition
 
subject: Why this(a) be rejected by compiler?
 
Similar Threads
Reg. abstract class and method
q on abstract class
abstract
basic OO question
help me on output of this code