给出以下假设类型层次结构:
BaseElement
+ StringElement
+ ....
+ ....
+ BooleanElement
+ ....
+ ....
+ ...
我有一个类接口:
IBaseElementService createElementService(Class<? extends BaseElement> element);
IBooleanElementService createElementService(Class<? extends BooleanElement> element);
这在eclipse 3.4中编译得很好,但在eclipse 3.6中不再编译,失败并出现错误:
Method ... has the same erasure createElementService(Class<T>) as another method in this type
我有点疑惑为什么这个在eclipse 3.4下编译,因为java编译器删除了这个类型。但无论如何,有没有一种优雅的方法来改变它而不重命名方法?
谢谢!
编辑:正如多人所指出的,这似乎是一个日食3.4 - 3.5的错误。 eclipse bug report(感谢denis.solonenko的链接!)
如果有人对此错误的技术细节感兴趣,请务必阅读PaŭloEbermann的帖子,thx!
答案 0 :(得分:1)
重命名方法。 (但为什么你有两种方法?也许第一种方法应该是唯一的方法;它可以检查类类型并转发到BooleanElement的第二种方法)
根据当前的语言规范,您的两个方法应该编译。见here。我在Java 7中听说过这两种方法不能再存在了。不确定理由。
答案 1 :(得分:0)
您可以将通用添加到IBaseElementService
。
在creaseElementService中,您需要进行一些检查以返回正确的元素服务。
IBaseElementService<T> createElementService(Class<T extends BaseElement> elementClass) {
if (elementClass.equals(BooleanElement.class))
return new IBooleanElementService();
return new IBaseElementService();
}
public class IBooleanElementService implements IBaseElementService<BooleanElement> { ... }
public class IBaseElementService implements IBaseElementService<BaseElement> { ... }
答案 2 :(得分:0)
在VM级别,方法签名也包括返回类型。因此,您的两种方法都有签名
createElementService(Class):IBooleanElementService
和createElementService(Class):IBaseElementService
。只要编译器知道要调用哪个方法,它就可以将调用放在字节码中的正确方法中。我认为这就是Eclipse 3.4所做的。
在Java语言级别上,方法仅通过名称和参数类型进行区分。您的方法在此处具有签名createElementService(Class<? extends BooleanElement>)
和createElementService(Class<? extends BaseElement>)
。但语言规范说明了它们将被删除的泛型类型 - 它们都被删除到createElementService(Class)
,现在它们根本没有不同,这是不允许的。
我认为3.4编译器在这里有一个错误(即它编译的语言不是真正的Java)。