6
static <V> void myMethod(Map<?, V> map)
{
 Iterator<Entry<?, V>> it = map.entrySet().iterator();
}

以下のコンパイル エラーが表示されます:
Type mismatch: cannot convert from Iterator<Map.Entry<capture#5-of ?,V>>toIterator<Map.Entry<?,V>>

4

1 に答える 1

10

試す

Iterator<? extends Entry<?, V>> it = map.entrySet().iterator();

あなたの試みがうまくいかない理由は、特にIterator<T>何も消費しない(つまり、パラメータとして aTを取るメソッドがない)ため、わかりにくいです。T

を に代入できないのと同じ理由で、 を に代入することはできIterator<Entry<capture#5-of ?,V>>ません。は、メソッドのパラメーターで見つかった特定のものを他の個別のワイルドカード インスタンスと区別するために使用される単なる名前です。具象型にすることも簡単にできます。Iterator<Entry<?, V>>Iterator<Entry<Integer, String>>Iterator<Entry<?, V>>capture#5?

これが機能しない理由は、代わりに のIteratorようなクラスを考えるとより明確になりますList

List<Entry<Integer, String>> entries = new ArrayList<>();

//this is a compile error, but assume it is possible
List<Entry<?, String>> wildcardEntries = entries; 

//then since this is already possible
wilcardEntries.add(new Entry<String, String>("a", "b"));
Entry<Integer, String> entry1 = entries.get(0);

//this would result in a type error (ClassCastException)
Integer i = entry1.getKey();

使用? extends Entry<?, V>することで、これにさらされることはありません。消費できるタイプについて何も知っているとは主張せず、それが生成できるものだけEntryを知っていると主張しているわけではありません。Iterator

編集

ジマンは彼の答えを削除しましたが、for-each ループを使用することは、この問題を完全に回避するためのよりクリーンなアプローチであるという良い点がありました (エントリを反復処理しようとしているだけだと仮定します)。これはうまくいくはずです:

for ( Entry<?, V> entry : map.entrySet() ) {
   //...
}
于 2012-11-10T07:14:46.083 に答える