Reputation: 145
I am familiar with static
keyword, and how it used. I understand that a static
method can be re-declared in sub-class but its definition gets hidden and remains same as of parent class. I am mentioning some links of articles I've already read:
https://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/
Why doesn't Java allow overriding of static methods?
Difference between Static and final?
When a derived class defines a static method with same signature as a static method in base class, the method in the derived class hides the method in the base class. But still the method of base class is called such as display()
method of base class.
But I am curious as to why and when there is a need to re-declare static
method of base class
in derived class if its definition cannot
overridden/altered in the derived class and the definition of base class is displayed instead?
/* Java program to show that if static method is redefined by
a derived class, then it is not overriding. */
// Superclass
class Base {
// Static method in base class which will be hidden in subclass
public static void display() {
System.out.println("Static or class method from Base");
}
// Non-static method which will be overridden in derived class
public void print() {
System.out.println("Non-static or Instance method from Base");
}
}
// Subclass
class Derived extends Base {
// This method hides display() in Base
public static void display() {
System.out.println("Static or class method from Derived");
}
// This method overrides print() in Base
public void print() {
System.out.println("Non-static or Instance method from Derived");
}
}
// Driver class
public class Test {
public static void main(String args[ ]) {
Base obj1 = new Derived();
// As per overriding rules this should call to class Derive's static
// overridden method. Since static method can not be overridden, it
// calls Base's display()
obj1.display();
// Here overriding works and Derive's print() is called
obj1.print();
}
}
Upvotes: 0
Views: 398
Reputation: 1074495
The main take-away here is: Don't use instance variables to call static
functions. Java allows it, but it's confusing because it looks like an instance method call when it isn't.
This line creates a Derived
instance, and assigns it to a Base
-typed variable:
Base obj1 = new Derived();
Later, when you type:
obj1.display();
what really happens is:
Base.display();
because obj
is a variable of type Base
and display
is a static
method. In fact, if you look at the compiled bytecode, you see that it's literally that call, the instance variable isn't mentioned anywhere:
public class Test { public Test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2 // class Derived 3: dup 4: invokespecial #3 // Method Derived."":()V 7: astore_1 8: aload_1 9: pop 10: invokestatic #4 // Method Base.display:()V 13: aload_1 14: invokevirtual #5 // Method Base.print:()V 17: return }
Notice the difference between the obj1.display()
call
10: invokestatic #4 // Method Base.display:()V
and the obj1.print()
call:
13: aload_1 14: invokevirtual #5 // Method Base.print:()V
The static
call doesn't push obj1
on the stack, and uses invokestatic
. The instance call does push obj1
on the stack (aload_1
), and calls invokevirtual
.
If you declared obj1
of type Derived
, you'd see the opposite behavior. With:
Derived obj1 = new Derived();
then
obj1.display();
outputs:
Static or class method from Derived
because it's really:
Derived.display();
It's all about the type of the instance variable. The type of the instance itself doesn't matter at all (in fact, obj1
could be null
).
Don't call static
methods via instance variables. Instead, use the class name.
I understand that a
static
method can be re-declared in sub-class but its definition gets hidden and remains same as of parent class....
When a derived class defines a
static
method with same signature as a static method in base class, the method in the derived class hides the method in the base class.
Those two statements contradict each other. The relationship is this: The derived static
method overrides the base static
method when referenced via the derived class. So with your code, Base.display
references Base.display
and Derived.display
references Derived.display
. The fact there's a display
on Derived
doesn't affect the one on Base
, which is still accessible via Base
(or a Base
-typed variable). (If you didn't have display
in Derived
, Derived.display
would reference Base.display
, but since you do, it doesn't.)
But I am curious as to why and when there is a need to re-declare static method of base class in derived class...
The only time you need that is if you want Derived.display
(or obj1.display
when obj1
is declared as Derived
) to do something different from Base.display
(or obj1.display
when obj1
is declared as Base
). One example I can think of is methods that create instances, perhaps via the Builder pattern:
Base b = Base.builder()
.setName("the name")
.setAnswer(42)
.setBiz("baz")
.build();
vs.
Derived d = Derived.builder()
.setName("the name")
.setAnswer(42)
.setBiz("baz")
.setDerivedThingy("whatever")
.build();
Upvotes: 6
Reputation: 1313
There is no need for an instance while invoking static member or method.
Since static members belongs to class rather than instance.
Example 15.11.1-2. Receiver Variable Is Irrelevant For static Field Access
The following program will make your doubt clear.It demonstrates that a null reference can also be used to access a class (static) variable without causing any Null pointer exception:
class Test {
static String name = "Jaspreet";
static Test method1(){
System.out.print("Hello world");
return null;
}
public static void main(String[] args) {
System.out.println(method1().name);
}
}
And the analysis of why it is happening
Even though the result of method1() is null, a NullPointerException is not thrown. That "Hello world" is printed demonstrates that the Primary expression is indeed fully evaluated at run time, despite the fact that only its type, not its value, is used to determine which field to access (because the field name is static).
Upvotes: 1