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

Java泛型类型擦除方法签名问题,java,class,generics,type-erasure,Java,Class,Generics,Type Erasure,给定以下假设的类型层次结构: BaseElement + StringElement + .... + .... + BooleanElement + .... + .... + ... 我有一个如下形式的类接口: IBaseElementService createElementService(Class<? extends BaseElement> element); IBooleanElementServ

给定以下假设的类型层次结构:

BaseElement
  + StringElement
      + ....
      + ....
  + BooleanElement
      + ....
      + ....
  + ...
我有一个如下形式的类接口:

IBaseElementService    createElementService(Class<? extends BaseElement>    element);
IBooleanElementService createElementService(Class<? extends BooleanElement> element);
IBaseElementService createElementService(类重命名了方法。(但为什么有两个方法?也许第一个应该是唯一的公共方法;它可以检查类类型并转发到第二个BooleanElement方法)


根据当前的语言规范,您的两个方法应该可以编译。请参阅。我在Java 7中听说这两个方法不能再共存了。不确定其原理。

您可以向
IBaseElementService
添加泛型

在creaseElementService内部,您需要执行一些检查以返回正确的elementservice

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> { ... }
IBaseElementService createElementService(类elementClass){
if(elementClass.equals(BooleanElement.class))
返回新的ibooleElementService();
返回新的IBaseElementService();
}
公共类IBooleanElementService实现IBaseElementService{…}
公共类IBaseElementService实现IBaseElementService{…}

在VM级别,方法签名也包括返回类型。因此,您的两个方法都有签名
createElementService(类):ibooleElementService
createElementService(类):IBaseElementService
。只要编译器知道调用哪个方法,它就可以在字节码中调用正确的方法。我想这就是Eclipse 3.4所做的


在Java语言级别上,方法只根据名称和参数类型进行区分(ClassA类似的问题和答案:eclipse 3.4编译这个cade真的很奇怪!@salman.mirghasemi,引用的问题是不相似的。@Patrick理解为什么这个代码不起作用,并问eclipse 3.4如何编译它以及如何修改代码。问你提到的问题的人没有回答根本不理解擦除。可能与此错误报告有关。如果Eclipse 3.4编译它,这意味着存在错误,并且在Eclipse 3.6中已修复。编译器在各种重载方法中进行选择时应忽略返回类型。返回类型不是签名的一部分,因为调用方可能忽略返回值,例如调用方法int foo(inti)作为foo(5)。所以你的评论很有趣,但似乎不准确……虽然我没有更好的解释…@AlexR:eclipse3.4不是根据返回类型选择的,而是根据参数的类型参数选择的——返回类型仅用于VM区分。但是正如你所说(我说过),这在这里是错误的。我考虑过这种可能性,但更倾向于重命名方法,而不是使用反射机制。无论如何,谢谢!没错,我应该提到,如果两个接口之间存在显著差异,重命名是最好的方法。如果两个接口(几乎)相同,则此解决方案效果最好。
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> { ... }