Java泛型和方法签名

时间:2013-06-20 08:57:13

标签: java overloading

我试图在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>相同?对我没有意义。

8 个答案:

答案 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一样。这意味着您可以将任何内容放入指定的列表中,然后才能将ObjectStringClassAListener等添加到一个列表中。引入了泛型来指定他们将获得的类型的集合。这是: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>相同。

您只能使用不同的方法名称来解决此问题,或者,如果ClassAClassB具有相同的父级,请使用getResponse(List<? extends ClassABParent> param)

答案 7 :(得分:0)

这是因为编译器仍然支持遗留代码,这就是为什么它会考虑删除泛型类型。你可以在here中找到相同的问题。