Reputation: 1
Debugging sub-expression
Sub.x
in expression
System.out.println(Sub.x);
in given below code,to understand rule of class initialization in run-time for classes namely., class Sub
and class Super
in JVM memory space.
package defaultvalues;
import java.util.*;
class Super{
static int x;
static{
System.out.println("Super");
}
}
class Sub extends Super{
Date date;
{//instance initialisation block for date
Calendar temp = Calendar.getInstance();
date = temp.getTime();
}
static{
System.out.println("Sub");
}
long alarm;
}
class Game{
static Random rand;
static{
rand = new Random();
}
static void tossCoin(){
if(rand.nextBoolean()){
System.out.println("Heads");
}else{
System.out.println("Tails");
}
}
}
public class Example {
public static void main(String[] args) {
System.out.println(Sub.x); // class Super is loaded. From class Super, static members are
//initialised and static initialisation blocks are executed before executing expression 'Sub.x'
Game.tossCoin(); // class Game is loaded. From class Game, static members are initialised
//and static initialiser blocks are executed before executing expression 'Game.tossCoin()'
Sub obj = new Sub(); //instance variables are initialised and instance initialisation block
//of class A are executed.
System.out.println(obj.date);
System.out.println(obj.alarm);
}
}
After debug, observation is that, class Super
gets initialized but class Sub
does not get initialised before expression Sub.x
gets evaluated. Immediate output after evaluating expression System.out.println(Sub.x);
is:
Super
0
So, System.out.println("Sub");
does not execute before expression Sub.x
gets evaluated.
With respect to this expression Sub.x
evaluation, in source code, I see the expression Sub.x
getting evaluated, class Super
gets initialized but not class Sub
.
My question is:
Does class Sub
get loaded & linked but not initialized before evaluating sub-expression Sub.x
during run-time?
Note: Working in Eclipse environment
Upvotes: 0
Views: 257
Reputation: 280122
The behavior you describe is given in an example in the JLS, here
Example 12.4.1-2. Only The Class That Declares static Field Is Initialized
class Super { static int taxi = 1729; } class Sub extends Super { static { System.out.print("Sub "); } } class Test { public static void main(String[] args) { System.out.println(Sub.taxi); } }
This program prints only:
1729
because the class
Sub
is never initialized; the reference toSub.taxi
is a reference to a field actually declared in classSuper
and does not trigger initialization of the classSub
.
which matches the list of initialization causes
- A static field declared by
T
is used and the field is not a constant variable (§4.12.4).
The field is declared by Super
, not Sub
.
Upvotes: 3
Reputation: 40418
It's because you haven't triggered static class initialization
yet.
In the answer to a related question, here, the answer talks about the various ways to trigger class initialization.
If you made a method getX()
in class Sub
which returns x
from it's superclass, it should perform static class initialization for Sub
.
Some more reading in JLS-12.4.1.
Note in this case that "A static field declared by T is assigned." does not seem to apply, since x
was declared in the superclass.
Upvotes: 2