I have the following code:
class SuperClass {
public static String getName() { return "super"; }
}
class SubClass extends SuperClass {
public static String getName() { return "sub"; }
}
public class Dummy<T extends SuperClass> {
public void print() {
System.out.println("SuperClass: " + SuperClass.getName());
System.out.println("SubClass: " + SubClass.getName());
System.out.println("T: " + T.getName());
}
public static void main(String[] args) {
new Dummy<SubClass>().print();
}
}
This code outputs the following:
SuperClass: super
SubClass: sub
T: super
My question is: Why doesn't T.getName() return the value of SubClass.getName()? After all, I specified that T == SubClass. Or are static function calls invalid for generic references?
Thanks a lot in advance!
This isn't just an issue about generics.
If you say:
SuperClass obj = new SubClass();
System.out.println(obj.getName());
you will also get "super". There are no "polymorphic" static methods.
In your case, all the compiler knows about T
is that it extends SuperClass
, so it will call SuperClass.getName()
.
Unlike C++ templates, Java generics work by type erasure, so it only generates one class for all values of T
, and translates all references to type T
in this class to the super type of T
, in this case SuperClass
, then uses virtual dispatch to provide the variance for calls to object methods, and static dispatch to calls to static methods.
So when you do Dummy<SubClass>.print()
, the compiler does not make a global replace of T
with SubClass
in Dummy
. All the compiler does is check that uses of T
as an argument or return type in the methods of Dummy
are SubClass
. There's no change to any code inside Dummy
, so the same SuperClass
static method gets called whatever T
is.
If you want different behaviour in a generic class depending on the parameterised type, you have pass an object of that type in and use a virtual method, or pass in the class for the type and use reflection.
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