1

次の方法がある場合:

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

その後type erasure、コンパイラが原因でになりdoSomething(List<Number> l)ます。右?
この場合、これと一緒に次のことを宣言できないのはなぜですか。

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

この2番目の方法ではありませんtype eraseddoSomething(List<Object> l)?これら2つのメソッドで同じ消去のコンパイラエラーが発生するのはなぜですか?

4

3 に答える 3

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) {      
}  

この場合、シグニチャの衝突はありません。

于 2012-08-15T15:29:52.387 に答える
2

?ジェネリックスでワイルドカードとして使用されます。

消去されます。

U extends Number上限が数値であることを示します

List<?>上界と下界はわかりません。

編集:編集された質問に基づいて、コンパイル後、バイトコードには含まれています。

public void doSomething(List argument) {      
}  
public void doSomething(List argument) {      
}  

ジェネリックスの継承は、Javaの継承として知られているものと少し異なります。

于 2012-08-15T15:28:13.910 に答える
1

1. ?ジェネリックスでワイルドカードとして使用されます。

例えば:

動物がクラスであると仮定します。

ArrayList<? extends Animal>動物を拡張する任意のクラスのインスタンスを 意味します

の間にErasureコンパイラがコンパイル時にクラスとメソッドのジェネリックを削除して、ジェネリックが導入されなかったときに作成されたコードと互換性のあるジェネリックコードを作成するプロセスです。

したがって?、時間U中に削除されます。実行時に削除されます。compilation

于 2012-08-15T15:31:58.947 に答える