If I have a base class like this that I can’t change:
public abstract class A {
public abstract Object get(int i);
}
and I try to extend it with a class B like this:
public class B extends A{
@Override
public String get(int i){
//impl
return "SomeString";
}
}
everything is OK. But my attempt to make it more generic fails if I try:
public class C extends A{
@Override
public <T extends Object> T get(int i){
//impl
return (T)someObj;
}
}
I can’t think of any reason why this should be disallowed. In my understanding, the generic type T is bound to an Object—which is the requested return type of A. If I can put String or AnyObject as my return type inside B, why am I not allowed to put <T extends Object> T inside my C class?
Another strange behavior, from my point of view, is that an additional method like this:
public class D extends A{
@Override
public Object get(int i){
//impl
}
public <T extends Object> T get(int i){
//impl
}
}
is also not allowed, with the hint of a DuplicateMethod provided. This one, at least, confuses me, and I think Java should make a decision: if it is the same return type, why not allow overriding; and if it is not, why shouldn’t I be able to add this method? To tell me it’s the same, but not allow it to be overridden, is very weird, based on common sense.
JLS # 8.4.2. Method Signature
As per above rule as your parent do not have an erasure and your child has one so it is not a valid overriding.
JLS#8.4.8.3. Requirements in Overriding and Hiding
Example 8.4.8.3-4. Erasure Affects Overriding
A class cannot have two member methods with the same name and type erasure:
This is illegal since D.id(Object) is a member of D, C.id(String) is declared in a supertype of D, and:
C.id(String)
Two different methods of a class may not override methods with the same erasure:
This is also illegal, since D.id(String) is a member of D, D.id(Integer) is declared in D, and:
subsignature of the other)
overrides I.id(Integer) yet the two overridden methods have the same
erasure
Also It gives example of a case where it is allowed from super to child
Consider the example:
}
Now, assume this code was written before the introduction of generics, and now the author of class CollectionConverter decides to generify the code, thus:
Without special dispensation, Overrider.toList would no longer override CollectionConverter.toList. Instead, the code would be illegal. This would significantly inhibit the use of generics, since library writers would hesitate to migrate existing code.