• 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
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

class initialization

 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In the assertion guide,
http://java.sun.com/j2se/1.4.1/docs/guide/lang/assert.html#design-faq-enable-disable
the following question (8) is presented.
�Why does an assert statement that executes before its class is initialized behave as if assertions were enabled in the class?�
The answer begins
�Few programmers are aware of the fact that a class�s constructors and methods can run prior to its initialization.�
Would you please explain this sentence (independent of the question)?
 
Ranch Hand
Posts: 298
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Could someone, please, explain the question and when a constructor or a method will run prior to the class initialization?
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is possible that if you extend a class and override a method that the parent class calls within it's constructor, then your overridden method may be called before your class has completed it's construction.
Please try running the following code:

You should see:
a = 0
Test Incrementer
a = 2
Test constructor
a = 0
final result: 0
The reason Test.a got reset back to zero was that it had been incremented prior to it being initialised. Hence the variable.
Likewise the method Test.incrementA was executed before Test was initialized.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Andrew for your example.
I found another clue in the assertion spec, section Semantics. �It is possible, though generally not desirable, to execute methods or constructors prior to initialization. This can happen when a class hierarchy contains a circularity in its static initialization...�
They also give an example, but not one that executes a constructor before a static initializer.
Leandro, the answer to the question (in the assert guide, last page, question 8) may help to explain the question.
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I found another clue in the assertion spec, section Semantics. �It is possible, though generally not desirable, to execute methods or constructors prior to initialization. This can happen when a class hierarchy contains a circularity in its static initialization...�
They also give an example, but not one that executes a constructor before a static initializer.


You have a point here, Marlene. The example given is about initialization of an instance of a class. The initialization of a class, however, is the execution of the static initializers. It is done, tipically, just before the first instance is created, or the first time a static member is accessed.
See JLS 12.4 for more.
By the way, welcome to the Ranch Andrew.
[ April 04, 2003: Message edited by: Jose Botella ]
 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In Andrew's example - Why does the parent constructor use the child's (the overriden) method and not it's own? It seems very strange.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
>>Why does the parent constructor use the child's (the overriden) method and not it's own?
An object of class Test is being created.
Test b = new Test();
At run-time, the virtual machine chooses the method in Test instead of the method in TestParent, because (1) the class of the object is Test and (2) the method declared in Test overrides the method declared in TestParent.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Martin, here is another example.
 
Martin Smith
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
you are right, is it the other way tho. with fields?
If the inherited method uses the overriden method. Should not the inherited method use the overriden field?

 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Martin,
"Overriding a variable" is called "shadowing" the variable. You will need to get used to this naming, as it is used in the exam. The technical difference is that the variable is not really overriding, it is just hiding behind the shadow of the variable you wish to use.
Generally speaking, the overridden method will use the shadowing field.
Be aware though that shadowing fields deliberately is very bad practice, as there can be side effects.
The following code should show you both the fact that the shadowing fields are being used in the overridden methods, and also show you one of the side effects:

The output should be:
5 == 5
5 != 3 (this is the side effect)
In both cases, the virtual machine uses the overridden method and the shadowing variable within that overridden method.
However, when I referred directly to A.x, I got the shadowed variable, not the shadowing variable! This is because, unlike a method call, references to variables are determined at compile time not runtime.
Hope this hasnt confused you too much.
Regards, Andrew
[ April 07, 2003: Message edited by: Andrew Monkhouse ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

If the inherited method uses the overriden method. Should not the inherited method use the overriden field?


Martin, the compiler chooses which declaration of a field to use.
In your example, the compiler first looks for a local variable declaration or a visible parameter declaration in the method print() for the name v. Not finding one, the compiler then looks for a visible field declaration for the name v. The compiler is compiling class A and finds a field declaration for v in A.
Compare these 3 cases:
1. The compiler chooses which (possibly overloaded) form of a declaration and at run-time the virtual machine chooses which implementation of an instance method to use.
2. The compiler chooses which declaration of a field (instance or static) to use.
3. The compiler chooses which declaration of a class (static) method to use.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

If the inherited method uses the overriden method


Martin, I am guessing what you meant here is �if an instance of the subclass uses the overridden method�. Correct me if I am wrong.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Andrew,

"Overriding a variable" is called "shadowing" the variable.


A field declaration hides a field declaration in a superclass or superinterface. (JLS 8.3) A field declaration shadows a field declaration in an enclosing class. A local variable and a parameter variable shadow a field. (JLS 6.3.1)

In both cases, the virtual machine uses the overridden method and the shadowing variable within that overridden method.

The virtual machine uses the overriding method, not the overridden method.
(The virtual machine uses but the compiler chooses the variable.)
[ April 07, 2003: Message edited by: Marlene Miller ]
 
Martin Smith
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I get it..
The *compiler* always works out which variable (based on the class).
Runtime decision is only on instance methods (based on the underlying object).
... so i *think* you are saying that the subclass infact contains 2 identical variables, just you can't access the hidden one.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I think I get it

This idea takes a while to develop roots. The more examples I see, the more I understand.

The *compiler* always works out which variable (based on the class).

Yes. The compiler determines which declaration of a variable to use.

Runtime decision is only on instance methods (based on the underlying object).

Yes. There are compile-time steps and run-time steps to choose an instance method.

the subclass in fact contains 2 identical variables,

Yes. When an object is created, memory is allocated for all the instance variables declared in the class and all the instance variables declared in each superclass, including all the instance variables that may be hidden.

just you can't access the hidden one.

When compiling class A, the compiler does not consider the declaration in the subclass B. At compile-time, the declaration of v in A is not hidden from the method print() in A.
When compiling class B, the declaration of v in A is hidden from code declared in class B.
You cannot access the hidden variable declared in A from code in B using the simple name v. But you can access it using super.v
Keep asking questions and restating what you think and trying examples. You are getting it.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic