0

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

7
  • Probably. If you compile with -Xlint, does the compiler issue a warning that a variable x is being accessed through a sub class? Commented Jun 16, 2015 at 15:58
  • "Under the hood, Does javac compiler translate expression Sub.x to Super.x before execution?" You can check that yourself: run javap -c Example.class from the console and see. Commented Jun 16, 2015 at 16:15
  • @Tom javap shows this: 3: getstatic #22; //Field defaultvalues/Sub.x:I How do I understand this line? Commented Jun 16, 2015 at 16:22
  • So, the compiler doesn't replace something there. It load the static variable Sub.x of type Integer. Commented Jun 16, 2015 at 16:23
  • @Tom If compiler does not replace expression Sub.x with Super.x, then, why class Sub does not get loaded before sub-expression Sub.x gets evaluated? Commented Jun 16, 2015 at 16:23

2 Answers 2

3

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 to Sub.taxi is a reference to a field actually declared in class Super and does not trigger initialization of the class Sub.

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.

Sign up to request clarification or add additional context in comments.

10 Comments

For your point: "because the class Sub is never initialized", I understood this point, but how do I verify/confirm if class Sub is loaded/linked to JVM instance before sub-expression Sub.x gets evaluated?
@overexchange What specific behavior do you mean by loaded? Also, why do you need to confirm it? Seems like a design smell.
Am talking about these phases, when I say loaded/linked. As java programmer, I feel, It is important for me to know, whether class Sub is loaded in this situation.
@overexchange You can read the rules of loading in the document you linked to, but, again, what difference will it make whether you know if it happens for your class or not? (Unless you're debugging some classloader issue, but there are better ways to do that.)
@overexchange You can use techniques described here to investigate.
|
2

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.

4 Comments

Can I say, class Sub gets loaded & linked but not initialized before expression Sub.x is evaluated?
Yes, I believe that is true.
Can I confirm this by writing java code(to verify load/link) in the above program?
The line Sub obj = new Sub(); already triggers static class initialization of class Sub, but if you want to trigger it earlier, you can for example just add this to Sub class: static int n; and then access it somehow, e.g. System.out.println(Sub.n);.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.