2013-06-20 46 views
4

我试着使用Java创建重载方法:Java的泛型和方法签名

private BasesResponse getResponse(List<ClassA> classA) { 
... 
} 

private BasesResponse getResponse(List<ClassB> classB) { 
    ... 
} 

但是Eclipse抱怨:方法getResponse(List<ClassA>)具有相同的擦除getResponse(List<E>)在类型BasisInformationEndpoint另一种方法。

我认为方法签名是方法名称+参数列表....但List<ClassA>如何可以List<ClassB>?对我来说没有意义。

+3

阅读关于类型擦除:http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Type%20Erasure –

+0

它确实有意义,这是一个很好的问题。我相信有人会为你输入一个很好的解释。 –

+0

一旦你了解[Type Erasure](类型擦除)(http://docs.oracle.com/javase/tutorial/java/generics/erasure.html),你就会明白为什么它是 –

回答

2

泛型类型(<...>)仅在编译阶段出现才用于静态类型。

一旦编译,这些类型被“擦除”,并且List<ClassA>实质上变成List。因此,你可以看到,当这种情况发生时,你的两个功能变得完全相同

这被称为类型删除,正如评论者所提到的那样。

5

的Java generic type erasure将使

private BasesResponse getResponse(List classA) { 
... 
} 

private BasesResponse getResponse(List classB) { 
    ... 
} 

后类型擦除它是编译器相同。

1

这是不可能的。为了向后兼容,泛型参数在运行时被丢弃(不像在C#中)。这被称为类型擦除。因此在运行时,List<Whatever>只是一个List。这意味着你的两个方法都有一个BasesResponse getResponse(List)的原型,这是一个编译错误。

1

通用方法参数中的Java编译器也是erases type parameters

您可能会看到两个参数为不同类型的,但是当<>被删除JVM将看到两种方法的参数的类型。

因此,重载失败。

1

泛型类型擦除:

这样做的原因实际上是由于仿制药,List<ClassA>List<ClassB>的Java 1.5之前没有发现任何仿制药,名单被宣布为是。正如List。这意味着你可以把任何东西在指定的列表中,这将是合法的只添加ObjectStringClassAListener等,以一个列表中。泛型被引入用于指定它们将获得的类型的集合。这就是:List<ClassA>List<String>等也发挥了作用。但是为了保留那些创建系统预泛型时间的人的遗留系统,这将是一个问题,泛型只是强加编译时间,但是在运行时它仍然是相同的基础List之前。

因此,要回答你的问题,到Eclipse这是两个同样的方法签名接收一个参数:

private BasesResponse getResponse(List classX) { ... }

0

因为对于的JavaList<ClassA>List<ClassB>类型参数是一样的List<E> 。如果ClassAClassB具有相同的父级,请使用getResponse(List<? extends ClassABParent> param)

0

这是因为编译器还支持传统的代码,这就是为什么它抹去泛型类型considering.you可以找到同样的问题在here

1

回答这是因为通过type erasure会后两种方法就出来是这样的:

private BasesResponse getResponse(List classA) { 
... 
} 

private BasesResponse getResponse(List classB) { 
    ... 
} 

两个具有相同签名的相同方法。哪一个不是重载,而是一个编译时错误。