繁体   English   中英

Java泛型和方法签名

[英]Java Generics and Method signature

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

Java 泛型类型擦除将使它成为现实

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

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

类型擦除后,对于编译器是相同的。

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

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

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

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

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

Java编译器还会擦除通用方法参数中的类型参数

您可能会看到这两个参数是不同的类型,但是当除去<>时,JVM将把两个方法视为它们的参数类型。

因此重载失败。

通用类型擦除:

这样做的原因实际上是由于泛型, List<ClassA>List<ClassB>在Java 1.5之前,没有任何泛型,所以List被声明为是。 就像List 这意味着您可以将任何内容放入指定的列表中,然后才可以将ObjectStringClassAListener等仅添加到一个列表中。 引入了泛型来指定集合将要获得的类型。 在这里: List<ClassA>List<String>等开始播放。

但是,为了保留创建系统前泛型时间的那些人的遗留系统,这将是一个问题,泛型仅被强加编译时间,但在运行时,它仍将是以前的基础List。

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

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

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

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

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

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

因为对于JavaList<ClassA>List<ClassB>类型参数与List<E>

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

这是因为编译器仍支持旧版代码,这就是为什么它考虑删除通用类型的原因。您可以在此处找到相同的问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM