• 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

Why this(a) be rejected by compiler?

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

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
 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 195
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 216
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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:


 
James Du
Ranch Hand
Posts: 186
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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).]
 
Ranch Hand
Posts: 3141
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
James Du
Ranch Hand
Posts: 186
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 3141
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 186
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


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
Posts: 186
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 186
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi java gurus, pls. don't let my question drowned without sound!
Trust me, it worth the effort.
 
Jane Griscti
Ranch Hand
Posts: 3141
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 186
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Can you shoot lasers out of your eyes? Don't look at this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic