What are the rules dictating the inheritance of static variables in Java?

Solution 1:

I don't understand why the contents of foo vary depending on what class you're accessing it from.

Basically it's a matter of type initialization. The value of foo is set to "bar" when Sub is initialized. However, in your Testing class, the reference to Sub.foo is actually compiled into a reference to Super.foo, so it doesn't end up initializing Sub, so foo never becomes "bar".

If you change your Testing code to:

public class Testing {
    public static void main (String[] args) {
        Sub.main(args);
        System.out.println(Super.foo);
        System.out.println(Sub.foo);
        System.out.println(Super.foo);
    }
}

Then it would print out "bar" four times, because the first statement would force Sub to be initialized, which would change the value of foo. It's not a matter of where it's accessed from at all.

Note that this isn't just about class loading - it's about class initialization. Classes can be loaded without being initialized. For example:

public class Testing {
    public static void main (String[] args) {
        System.out.println(Super.foo);
        System.out.println(Sub.class);
        System.out.println(Super.foo);
    }
}

That still prints "foo" twice, showing that Sub isn't initialized - but it's definitely loaded, and the program will fail if you delete the Sub.class file before running it, for example.