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?
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.
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 ; ...
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With