Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a class, Super:

public class Super {     public static String foo = "foo"; } 

I also have another class, Sub that extends Super:

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

When I run it, it prints out bar.
My third (and last) class is Testing:

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

This prints:

foo foo foo 

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

like image 840
jmgrosen Avatar asked Mar 27 '12 21:03

jmgrosen


People also ask

Can static variables be inherited in Java?

Static methods take all the data from parameters and compute something from those parameters, with no reference to variables. We can inherit static methods in Java.

How variables are inherited in Java?

Classes in Java exist in a hierarchy. A class in Java can be declared as a subclass of another class using the extends keyword. A subclass inherits variables and methods from its superclass and can use them as if they were declared within the subclass itself: class Animal { float weight ; ...

How do you handle static variables in Java?

Static variables can be accessed by calling with the class name ClassName. VariableName. When declaring class variables as public static final, then variable names (constants) are all in upper case. If the static variables are not public and final, the naming syntax is the same as instance and local variables.

Is static can be inherited?

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.


1 Answers

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.

like image 169
Jon Skeet Avatar answered Sep 26 '22 05:09

Jon Skeet