2016-06-01 2 views
4

わかりませんgeneric wildcard bounderies ussage。
processMapが次の例のコンパイルエラーで失敗するのに対して、なぜがうまく機能するのか説明してください。どのように私はトリック複合型ワイルドカードバウンス

public void processMap(Map<String, List<? extends Object>> map) 
public <T extends Object> void processMap(Map<String, List<T>> map) 

を作っparametherメソッドにメソッドの引数の型からジェネリック型定義を考え動かしながら、それはMap<String, List<String>>Map<String, List<Object>>

public void processList(List<? extends Object> list) { 
} 

public void processMap(Map<String, List<? extends Object>> map) { 
} 

public void f() { 
    List<String> list = new ArrayList<>(); 
    Map<String, List<String>> map = new HashMap<>(); 

    processList(list); // OK 
    processMap(map); // ERROR 
} 

の両方で動作するようにprocessMapの署名を変更する必要があります今は両者の違いを知りたい。 another threadに移動しました。

+0

私は正解かどうかわかりませんが、Javaコンパイラが解決できないか、問題で定義されたマップコレクションのキーとして使用されているコレクションの種類を変換できないようです。私は 'public static void processMap(Map <?extends Object、List > map)'のように関数シグネチャを変更するとうまく動作するので、これを言っています。 ''と '<?extends Object>の間には大きな違いがあるようです。このような宣言で使用されるときには、Object> 'を拡張します。そのマルチレベルワイルドカードのコンセプト。 – qwerty

答えて

1

ワイルドカードを削除しても機能させることができます。私。あなたは、名前付きの型と総称関数を作成します。ワイルドカードでの機能が動作しない理由を<T extends Object>

public <T extends Object> void processMap(Map<String, List<T>> map) { 
} 

public void processList(List<? extends Object> list) { 
} 

public void f() { 
    List<String> list = new ArrayList<>(); 
    Map<String, List<String>> map = new HashMap<>(); 

    processList(list); // OK 
    processMap(map); // OK now 
    processMap(new HashMap<String, List<Integer>>()); // this is OK too 
} 

残念ながら、私が説明することはできません。

+0

これは、ワイルドカードキャプチャ(https://docs.oracle.com/javase/tutorial/java/generics/capture.html)と関係していると思います。 –

+0

ちょうど同じものを投稿しました。違いはあります。そこに 'extends Object'を置く必要はありません。あなたが使っているTは、あなたがコンパイラに伝えなくてもオブジェクトを拡張します;-) – GhostCat

+0

うん。 ''を使用しても問題ありません。 'extends'は' 'のようなものには良いです –

0
Map<String, List<? extends Object>> map = new HashMap<>(); 

f()メソッドで上記の変更を加えて動作させます。 Javaコンパイラは両方の変数が同じであるように変数のタイプをチェックします。私は間違っている可能性があります。

1

半分の答え:次のコードは私のためにコンパイルします。

見つからない:名前付きTがなぜ機能するのかについての良い説明。名前のない?ではない。

public <T> void processMap(Map<String, List<T>> map) { 
} 

public void f() { 
    Map<String, List<String>> map = new HashMap<>(); 
    processMap(map); 
    Map<String, List<Object>> map2 = new HashMap<>(); 
    processMap(map2); 
}