4

我试图在java中创建重载方法:

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

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

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

我认为方法签名是方法名称+参数列表....但是怎么能List<ClassA>一样List<ClassB>呢?对我来说没有意义。

4

8 回答 8

5

Java泛型类型擦除将使它

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

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

类型擦除后,编译器也是如此。

于 2013-06-20T09:04:11.260 回答
2

泛型类型 ( <...>) 仅在编译阶段之前存在,用于静态类型。

编译后,这些类型将被“擦除”并List<ClassA>实质上变为List. 因此,您可以看到,当这种情况发生时,您的两个功能变得相同。

正如评论者所提到的,这称为类型擦除。

于 2013-06-20T09:04:06.767 回答
2

通用类型擦除:

造成这种情况的原因实际上是由于泛型,List<ClassA>List<ClassB>java 1.5 之前没有任何泛型,List 被声明为原样。就像List. 这意味着您可以将任何内容放在指定的列表中,然后才可以合法地将Object, String, ClassA,Listener等添加到一个列表中。引入了泛型来指定它们将获得哪种类型的集合。这就是: List<ClassA>, List<String>, etc 发挥作用的地方。

然而,为了保留那些创建他们的系统预泛型时间的遗留系统,这将是一个问题,泛型只是强加的编译时间,但在运行时它仍然是之前相同的底层列表。

因此,要回答您的问题,对于 Eclipse,这是接收一个参数的相同方法签名:

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

于 2013-06-20T09:06:38.163 回答
1

这是不可能的。为了向后兼容,泛型参数在运行时被丢弃(与 C# 不同)。这称为类型擦除。

因此List<Whatever>,在运行时,a 只是一个List. 这意味着您的两个方法都有一个原型BasesResponse getResponse(List),这是一个编译错误。

于 2013-06-20T09:04:24.413 回答
1

Java 编译器还会删除泛型方法参数中的类型参数。

您可能会将这两个参数视为不同的类型,但当 <> 被移除时,JVM 会将两个方法视为其参数的类型。

所以重载失败。

于 2013-06-20T09:05:33.210 回答
1

这是因为在经过类型擦除之后,两种方法都会变成这样:

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

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

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

于 2013-06-20T09:07:35.483 回答
0

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

于 2013-06-20T09:07:13.303 回答
0

因为对于java和type 参数是一样List<ClassA>的。List<ClassB>List<E>

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

于 2013-06-20T09:06:50.123 回答