繁体   English   中英

Java Generics 类型擦除方法签名问题

[英]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):IBooleanElementServicecreateElementService(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM