Note: This question may seem similar to Java generic method inheritance and override rules, but I'm interested in why declaring the type parameter at the class level causes the compilation to pass.
In the following code, StringMaker2 successfully compiles when it implements Maker2<String>
However, StringMaker1 fails compilation when it implements Maker1 with:
GenericsTest.java: name clash: make(java.lang.Class<java.lang.String>) in GenericsTest.StringMaker1 and
<T>make(java.lang.Class<T>) in GenericsTest.Maker1 have the same erasure, yet neither overrides the other
The only different between Maker1 and Maker2 is that that the type parameter, <T>
, is defined at the method level in the former and class level in the later.
Could someone explain why this makes a difference?
public class GenericsTest {
interface Maker1 {
<T> T make(Class<T> type) throws Exception;
}
interface Maker2<T> {
T make(Class<T> type) throws Exception;
}
// This class fails compilation
class StringMaker1 implements Maker1 {
@Override
public String make(Class<String> type) throws Exception {
return type.newInstance();
}
}
class StringMaker2 implements Maker2<String> {
@Override
public String make(Class<String> type) throws Exception {
return type.newInstance();
}
}
}