[英]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>
相同? 对我没有意义。
泛型类型( <...>
)仅在编译阶段之前存在,用于静态类型化。
编译后,这些类型将被“擦除”,并且List<ClassA>
本质上成为List
。 因此,您可以看到,当发生这种情况时,您的两个功能将变得相同。
正如评论者所提到的,这称为类型擦除。
这是不可能的。 为了向后兼容,一般参数在运行时会被丢弃(与C#不同)。 这称为类型擦除。
因此, List<Whatever>
在运行时只是List
。 这意味着您的两个方法都具有BasesResponse getResponse(List)
的原型,这是一个编译错误。
通用类型擦除:
这样做的原因实际上是由于泛型, List<ClassA>
和List<ClassB>
在Java 1.5之前,没有任何泛型,所以List被声明为是。 就像List
。 这意味着您可以将任何内容放入指定的列表中,然后才可以将Object
, String
, ClassA
, Listener
等仅添加到一个列表中。 引入了泛型来指定集合将要获得的类型。 在这里: List<ClassA>
, List<String>
等开始播放。
但是,为了保留创建系统前泛型时间的那些人的遗留系统,这将是一个问题,泛型仅被强加编译时间,但在运行时,它仍将是以前的基础List。
因此,要回答您的问题,对于Eclipse,这是接收一个参数的两个方法签名:
private BasesResponse getResponse(List classX) { ... }
这是因为经过类型擦除后,这两种方法都会像这样:
private BasesResponse getResponse(List classA) {
...
}
private BasesResponse getResponse(List classB) {
...
}
具有相同签名的两种相同方法。 当然,这不是重载,而是编译时错误。
因为对于Java , List<ClassA>
和List<ClassB>
类型参数与List<E>
。
您只能使用不同的方法名称来解决此问题,或者,如果ClassA
和ClassB
具有相同的父代,请使用getResponse(List<? extends ClassABParent> param)
。
这是因为编译器仍支持旧版代码,这就是为什么它考虑删除通用类型的原因。您可以在此处找到相同的问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.