0

A file named TestClass.java has below lines of code

import java.util.*;

class Super { static String ID = "QBANK"; }

class Sub extends Super{
    static { System.out.print("In Sub"); }
}

public class TestClass{
    public static void main(String[] args) {
        System.out.println(Sub.ID);
    }
}

I was hoping get output when run TestClass.java file from command line as In Sub followed by QBANK but got only QBANK. If anyone could explain why static control flow for other two classes didn't execute.

stark
  • 399
  • 2
  • 13
Utpal Kumar
  • 425
  • 4
  • 11
  • `Sub` doesn't have a member `ID`: you're actually accessing `Super.ID`. There is no need to initialize the `Sub` class to access that. – Andy Turner Dec 25 '20 at 11:19
  • Andy, I did some digging and found out that a static variable of a class is inheritable. So Sub definitely has ID inherited from Super class. So I still didn't get my answer. – Utpal Kumar Dec 27 '20 at 13:32
  • Well, "static variable of a class is inheritable" is definately wrong. Could you share that source? – Dorian Gray Dec 27 '20 at 17:16
  • Of course I would. If you could look OCA 8, Kathy Sierra book page no 93. There is table stating the same. – Utpal Kumar Dec 27 '20 at 18:02
  • As a matter of fact, I still have that book for OCA available. I find that quote of her: "The static members aren't involved in runtime polymorphism" (page 53 in my edition), so there is no inheritance. You might want to quote that particular phrase, as not everyone has that book at home. And I am still unsure what this discussion has to to with the question in the first place. – Dorian Gray Dec 27 '20 at 18:31
  • Not: I have the book for OCA 7, so page numbers dont match – Dorian Gray Dec 27 '20 at 18:38
  • Mr. Gray, 'The static members aren't involved in runtime polymorphism' absolutely correct. But this is not entirely inheritance. While static fields/methods are inherited, they cannot be overridden since they belong to the class that declares them, not to the object references. If you try to override one of those, what you'll be doing is hiding it. please refer here - https://stackoverflow.com/a/17172112/4745890 – Utpal Kumar Dec 28 '20 at 10:25
  • Sure inheritance is part of polymorphism. I really dislike the word "inheritance" in regard to static members, it is misleading. It is merely a shared variable. – Dorian Gray Dec 28 '20 at 10:27

2 Answers2

0

Because the compiler replaces Sub.ID with Super.ID. Note that static fields are not inherited, Super.ID and Sub.ID are merely refering to the same variable. So the compiler decides that there is no need to load the class Sub.

Dorian Gray
  • 2,913
  • 1
  • 9
  • 25
  • First ID is not static constant in Super class, It is static member variable which is inheritable for their child class. So you are incorrect here. – Utpal Kumar Dec 27 '20 at 13:30
  • Nope, statics are not inheritable, `final` or not. Look at the declaration: `static String ID". There is exactly one instance. – Dorian Gray Dec 27 '20 at 17:15
  • Anyway, I added smth to my post, hope it makes some things more clear. – Dorian Gray Dec 27 '20 at 17:21
  • Please have a glance at OCA 8, Kathy Sierra book page no 93. There is table stating the same. Unless you define the static variable of same name in sub class, super class static variable is inherited. Or here in the program itself it is understood that if Sub.ID complies fine than it is inherited. But please refer the OCA book as I mentioned earlier. – Utpal Kumar Dec 27 '20 at 18:04
  • See my comment to the question. – Dorian Gray Dec 27 '20 at 18:34
0

If I compile your code and then decompile TestClass with javap, the main method is:

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: getstatic     #3                  // Field Sub.ID:Ljava/lang/String;
       6: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       9: return

So, yes, it does reference Sub.ID, not Super.ID.

Looking at the JVM Spec 5.5, it says:

A class or interface C may be initialized only as a result of:

  • The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references C (§new, §getstatic, §putstatic, §invokestatic).

Sounds like it should initialize Sub, because you've got a getstatic instruction referencing Sub.

But wait, there's more:

Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface to be initialized is the class or interface that declares the resolved field or method.

So: Super is the class that's initialized, because that's the one which declares the ID field. There's no need to initialize Sub at this point in the execution.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Yes Andy, I understood this now. Since Super class defines static variable therefore only Super is initialized not it's child who inherits the static variables. Thanks – Utpal Kumar Dec 27 '20 at 18:06