I have the following test code:
public interface Container<I> {
public void addClass(Class<?> clazz);
}
public class MyContainer implements Container {
public void addClass(Class<?> clazz) {}
}
and I get the following error when trying to compile these two class:
MyContainer.java:1: MyContainer is not abstract and does not override abstract method addClass(java.lang.Class) in Container
If I add a type to the Container interface in MyContainer (such as <Object>
), I don't get the error.
The problem is I'm introducing the type parameter to Container, which is part of the public API, so for compatibility, I can't have all implementing classes unable to compile.
Anyone have any ideas? Is it a type erasure issue? Is there a workaround?
I think the problem is that if you use raw types anywhere in the class declaration, you're sort of opting out of generics. So this will work - note the parameter change.
public class MyContainer implements Container {
public void addClass(Class clazz) {}
}
From section 4.8 of the JLS:
The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of its parameterized invocations.
I believe that's the relevant bit... the erasure of Container<T>.addClass(Class<?> clazz)
is addClass(Class clazz)
.
But yes, basically unless this is genuine legacy code, you should regard introducing a type parameter into an interface as a breaking change.