wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes class initialization Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "class initialization" Watch "class initialization" New topic
Author

class initialization

Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
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)?
Leandro Oliveira
Ranch Hand

Joined: Nov 07, 2002
Posts: 298
Could someone, please, explain the question and when a constructor or a method will run prior to the class initialization?
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11476
    
  94

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.


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
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.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120

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 ]

SCJP2. Please Indent your code using UBB Code
Martin Smith
Greenhorn

Joined: Apr 05, 2003
Posts: 22
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

Joined: Mar 05, 2003
Posts: 1391
>>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

Joined: Mar 05, 2003
Posts: 1391
Martin, here is another example.
Martin Smith
Greenhorn

Joined: Apr 05, 2003
Posts: 22
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
Marshal Commander

Joined: Mar 28, 2003
Posts: 11476
    
  94

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

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Apr 05, 2003
Posts: 22
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

Joined: Mar 05, 2003
Posts: 1391
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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: class initialization