什么是“?”的类型擦除?

时间:2012-08-15 15:27:32

标签: java generics

如果我有以下方法:

public <U extends Number> void doSomething(List<U> l){      
}  

然后由于type erasure,编译器会将其转到doSomething(List<Number> l)。对吗?
如果是这种情况,那么为什么不可能声明以下内容:

public void doSomething(List<?> l){  
}

这不是第二种方法type eraseddoSomething(List<Object> l)吗?为什么我会为这两种方法得到相同擦除的编译器错误?

3 个答案:

答案 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时间内删除..所以在运行时期间将会缺席