How come this compiles:
interface Test {
<T extends Integer> T getValue(T n);
}
class Impl implements Test{
public Integer getValue(Integer n) {
return n;
}
}
But this doesn't:
interface Test {
Integer getValue(Integer n);
}
class Impl implements Test{
public <T extends Integer> T getValue(T n){
return n;
}
}
It gives me the following compile error:
Impl is not abstract and does not override abstract method getValue(Integer) in Test
error: name clash: getValue(T) in Impl and getValue(Integer) in Test have the same erasure, yet neither overrides the other
Doesn't erasure ensure that T gets replaced with Integer? So why would the second example not be valid?
You are allowed to override a generic method with a non-generic one whose signature is the erasure of the generic method, but not the other way around. There's a good reason for this -- to allow supertypes to migrate to generics without forcing all the subclasses to migrate on the same day. So the compiler is tolerant of erased overrides. In the other direction, though, you are trying to override a non-generic method with a generic one, and there's no reasonable migration scenario that could produce that -- it's just an error.
The same is true for classes; you can write
class Foo<T> { }
class Bar extends Foo { }
but not
class Foo { }
class Bar extends Foo<T> { }
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments