如果我有以下方法:
public <U extends Number> void doSomething(List<U> l){
}
然后由于type erasure
,编译器会将其转到doSomething(List<Number> l)
。对吗?
如果是这种情况,那么为什么不可能声明以下内容:
public void doSomething(List<?> l){
}
这不是第二种方法type erased
到doSomething(List<Object> l)
吗?为什么我会为这两种方法得到相同擦除的编译器错误?
答案 0 :(得分:8)
你的想法是对的。擦除导致两种方法都具有此签名(List
参数类型被擦除):
public void doSomething(List l) {
}
因此,碰撞。你认为可以做到的是:
public <U extends Number> void doSomething(U argument) {
}
public <U extends Object> void doSomething(U argument) {
}
在这种情况下,擦除后,方法签名将变为此(在U
被删除后)
public void doSomething(Number argument) {
}
public void doSomething(Object argument) {
}
在这种情况下,没有签名冲突。
答案 1 :(得分:2)
?
在泛型中用作通配符。
它将被删除。
U extends Number
表示上限是数字
List<?>
并不知道上限是什么。
编辑:基于编辑过的问题,编译后,字节代码只包含。
public void doSomething(List argument) {
}
public void doSomething(List argument) {
}
Inheritance in generics与我们所知的java中的继承略有不同。
答案 2 :(得分:1)
1。 ?
在Generics中用作外卡。
<强>例如强>
假设动物是一个类。
ArrayList<? extends Animal>
表示任何类的实例,它扩展了Animal
在Erasure
,这是编译器在编译时删除类和方法中的泛型的过程期间,使Generics代码与编写时的代码兼容没有介绍泛型。
因此?
和U
将在compilation
时间内删除..所以在运行时期间将会缺席