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>>
試す
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() ) {
//...
}