[英]Java Generics Type Erasure Method Signature Problem
给定以下假设的类型层次结构:
BaseElement
+ StringElement
+ ....
+ ....
+ BooleanElement
+ ....
+ ....
+ ...
我有一个 class 接口,格式如下:
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 编译器删除了该类型。 但无论如何,有没有一种优雅的方法可以在不重命名方法的情况下改变它?
谢谢!
编辑:正如多人指出的那样,这似乎是一个 eclipse 3.4 - 3.5 错误。 eclipse 错误报告(感谢 denis.solonenko 提供链接!)
如果有人对此错误的技术细节感兴趣,请务必阅读 Paŭlo Ebermann 的帖子,谢谢!
重命名了方法。 (但是为什么你有两种方法?也许第一种应该是唯一的公共方法;它可以检查 class 类型并转发到 BooleanElement 的第二种方法)
根据当前的语言规范,您的两种方法应该可以编译。 看这里。 我听说在 Java 7 这样的 2 方法不能再共存了。 不确定其中的原理。
您可以向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> { ... }
在 VM 级别上,方法签名也包括返回类型。 因此,您的两个方法具有签名createElementService(Class):IBooleanElementService
和createElementService(Class):IBaseElementService
。 只要编译器知道调用哪个方法,它就可以将调用放到字节码中正确的方法。 我认为这就是 Eclipse 3.4 所做的。
在 Java 语言级别上,方法仅通过名称和参数类型来区分。 在这里,您的方法具有签名createElementService(Class<? extends BooleanElement>)
和createElementService(Class<? extends BaseElement>)
。 但是语言规范说它们将被删除的泛型类型 - 它们都被删除到createElementService(Class)
,现在它们根本没有什么不同,这是不允许的。
我认为 3.4 编译器在这里有一个错误(即它编译的语言不是真正的 Java)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.