无法编译实现没有类型参数的接口的类
我有以下测试代码:
public interface Container<I> {
public void addClass(Class<?> clazz);
}
public class MyContainer implements Container {
public void addClass(Class<?> clazz) {}
}
并且在尝试编译这两个类时出现以下错误:
MyContainer.java:1:MyContainer 不是抽象的,不会重写 Container 中的抽象方法 addClass(java.lang.Class)
如果我向 MyContainer 中的 Container 接口添加类型(例如
问题是我向 Container 引入了类型参数,它是公共 API 的一部分,因此为了兼容性,我不能让所有实现类都无法编译。
有人有什么想法吗?这是类型擦除问题吗?有解决方法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为问题在于,如果您在类声明中的任何位置使用原始类型,那么您就选择了退出泛型。所以这会起作用 - 请注意参数的变化。
来自 JLS 的第 4.8 节:
我相信这是相关的位...
Container.addClass(Class> clazz)
的删除是addClass(Class clazz)< /代码>。
但是,是的,基本上除非这是真正的遗留代码,否则您应该将类型参数引入接口视为重大更改。
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.
From section 4.8 of the JLS:
I believe that's the relevant bit... the erasure of
Container<T>.addClass(Class<?> clazz)
isaddClass(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.
如果
修复了它,则摆脱它:
错误消息不是很具有描述性:
这意味着当类型被擦除时,两个方法都是相同的,但子类方法不会实际上并没有实现/覆盖超类/接口中的一个。这没有多大意义,我认为这是因为您选择不在子类中使用泛型,您必须坚持这一点(而不是对
Class
进行参数化)Getting rid if the
<?>
fixes it:The error message is not very descriptive:
This would mean that both your methods are the same when their types are erased, but the subclass method does not actually implement/override the one from the superclass/interface. This does not make much sense, and I would assume that it's because you have chosen not to use generics in your subclass, you have to stick to that (and not perameterize
Class
)如果您的类使用泛型,那么一个简单的解决方案是这样做:
或者如果您已经知道您拥有的容器的类型,
如果您的类不使用泛型(1.5 之前),那么您不能拥有
< ;?>
部分。所以这里不会有任何真正的问题。If your class uses Generics then a simple solution would be to do this :
Or if you already know the type of Container you have,
If your class doesn't use Generics (pre 1.5) then you can't have the
<?>
part. So there won't be any real problem here.按如下方式实现您的接口应该可以工作(根据类型擦除):
Implementing your interface as follows should work (as per type erasure):