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.