我试图在java中创建重载方法:
private BasesResponse getResponse(List<ClassA> classA) {
...
}
private BasesResponse getResponse(List<ClassB> classB) {
...
}
但是eclipse抱怨:方法getResponse(List<ClassA>)
与BasisInformationEndpoint类型中的另一个方法具有相同的擦除getResponse(List<E>)
。
我认为方法签名是方法名称+参数列表....但List<ClassA>
如何与List<ClassB>
相同?对我没有意义。
答案 0 :(得分:5)
Java generic type erasure将成为
private BasesResponse getResponse(List classA) {
...
}
private BasesResponse getResponse(List classB) {
...
}
在类型擦除之后,编译器也是如此。
答案 1 :(得分:2)
泛型类型(<...>
)仅在编译阶段出现,用于静态类型。
编译完成后,这些类型会被“删除”,List<ClassA>
基本上会变成List
。因此,您可以看到,当发生这种情况时,您的两个功能变得相同。
这被称为类型擦除,正如评论者所提到的那样。
答案 2 :(得分:1)
这是不可能的。为了向后兼容,通用参数在运行时被丢弃(例如,与C#不同)。这称为类型擦除。
因此,List<Whatever>
在运行时只是List
。这意味着你的两个方法都有一个BasesResponse getResponse(List)
的原型,这是一个编译错误。
答案 3 :(得分:1)
Java编译器在泛型方法参数中也是erases type parameters。
您可能会将两个参数视为不同的类型,但是当&lt;&gt;时如果删除,JVM将会看到两个方法作为其参数的类型。
所以重载失败。
答案 4 :(得分:1)
通用类型擦除:
原因实际上是由于Generics,List<ClassA>
和List<ClassB>
在Java 1.5之前没有任何泛型,List被声明为。就像List
一样。这意味着您可以将任何内容放入指定的列表中,然后才能将Object
,String
,ClassA
,Listener
等添加到一个列表中。引入了泛型来指定他们将获得的类型的集合。这是:List<ClassA>
,List<String>
等进场的地方。
然而,为了保留那些创建系统pre-generics时间的遗留系统,这将是一个问题,泛型只是强制编译时间,但在运行时它仍然是之前相同的底层List。
所以为了回答你的问题,对于Eclipse,这是接收一个参数的相同方法签名:
private BasesResponse getResponse(List classX) {
...
}
答案 5 :(得分:1)
这是因为在经过type erasure之后,两种方法都会出现如下:
private BasesResponse getResponse(List classA) {
...
}
private BasesResponse getResponse(List classB) {
...
}
两个具有相同签名的相同方法。哪个过程不会重载,而是编译时错误。
答案 6 :(得分:0)
因为 java ,List<ClassA>
和List<ClassB>
类型参数与List<E>
相同。
您只能使用不同的方法名称来解决此问题,或者,如果ClassA
和ClassB
具有相同的父级,请使用getResponse(List<? extends ClassABParent> param)
。
答案 7 :(得分:0)
这是因为编译器仍然支持遗留代码,这就是为什么它会考虑删除泛型类型。你可以在here中找到相同的问题。