Hi, 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
Tis that it extendsSuperClass, so it will callSuperClass.getName().JeffreyHammansson : Ok, that's clear so far. But how can I then invoke the static method SubClass.getName() from Dummy using T? I would like to have many further subclasses with Dummy being able to invoke getName() transparently. -
When you instanciated the class with "new Dummy()" you called the default constructor which doesn't actually set anything. When print method got called, the VM saw that the type of T, as declared in the class declaration, is SuperClass; It then calls the static method on this class.
-
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 typeTin this class to the super type ofT, in this caseSuperClass, 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 ofTwithSubClassinDummy. All the compiler does is check that uses ofTas an argument or return type in the methods ofDummyareSubClass. There's no change to any code insideDummy, so the sameSuperClassstatic method gets called whateverTis.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.
0 comments:
Post a Comment