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?
Your class can implement more than one interface, so the implements keyword is followed by a comma-separated list of the interfaces implemented by the class. By convention, the implements clause follows the extends clause, if there is one.
The implements keyword is used to implement an interface . The interface keyword is used to declare a special type of class that only contains abstract methods. To access the interface methods, the interface must be "implemented" (kinda like inherited) by another class with the implements keyword (instead of extends ).
An interface declaration introduces a new reference type whose members are classes, interfaces, constants and abstract methods. This type has no implementation, but otherwise unrelated classes can implement it by providing implementations for its abstract methods.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With