2

次の両方のデータ型を受け入れるジェネリック関数を作成しようとしています

Map <Integer, Map<Integer, Long>>
Map <Integer, Map<Integer, Double>>

私の関数は次のようになります、

function(Map<Integer, Map<Integer, ? extends Number>> arg) {}

しかし、互換性のないタイプエラーが発生します。マップでは機能しますが、マップのマップでは機能しません。理由がわからないのですか?これを行う方法はありますか?

4

4 に答える 4

3

あなたは次のようなことを試すことができます

static <T extends Number> void function(Map<Integer, Map<Integer, T>> map) {}

public static void main(String[] args) {
    Map<Integer, Map<Integer, Long>> map1 = new HashMap<Integer, Map<Integer, Long>>();
    Map<Integer, Map<Integer, Double>> map2 = new HashMap<Integer, Map<Integer, Double>>();
    Map<Integer, Map<Integer, String>> map3 = new HashMap<Integer, Map<Integer, String>>();
    function(map1);
    function(map2);
    function(map3);// <-- compilation error here, String is not Number
}
于 2012-07-23T00:10:43.593 に答える
2

メソッドをパラメータ化してみませんか?

public <T extends Number> void function(Map<Integer, Map<Integer, T>>) { ... }

ワイルドカードキャプチャは、実際に何をするのかについて人々を混乱させる傾向があることがわかりました。

Map<Integer, ? extends Number>実際にはMap、キーがIntegerであり、値が。から派生したタイプであるものを意味しNumberます。これはを意味しMap<Integer, Integer>, Map<Integer,Long>ます。

このため、ワイルドカードが原因で、コンパイラは追加するために実際の型が何であるかを判断できないため、これらのコレクションに実際に追加することはできません。

于 2012-07-23T00:13:10.983 に答える
2

Setまず、代わりにsを使用して問題を減らしましょう。

Set<Set<Long>> longSetSet = null;
Set<Set<Double>> doubleSetSet = null;

Set<Set<? extends Number>> someNumberSetSet;

// try assigning them
someNumberSetSet = longSetSet;   //
someNumberSetSet = doubleSetSet; // compiler errors - incompatible types

一見すると、なぜこの割り当てが違法であるのか不思議に思うかもしれません。結局のところ、にを割り当てることができるSet<Long>からですSet<? extends Number>。理由は、ジェネリックが共変ではないためです。コンパイラは、にを割り当てることができないのと同じ理由で、Set<Set<Long>>にを割り当てることを防ぎます。詳細については、リンクされた回答を参照してください。Set<Set<? extends Number>>Set<Long>Set<Number>

回避策として、他の回答が示唆しているように、メソッドシグネチャでタイプパラメータを使用できます。別のワイルドカードを使用して、割り当てを合法にすることもできます。

Set<? extends Set<? extends Number>> someNumberSetSet;

someNumberSetSet = longSetSet;   //
someNumberSetSet = doubleSetSet; // legal now

またはあなたの例では:

function(Map<Integer, ? extends Map<Integer, ? extends Number>> arg) { }
于 2012-07-23T00:48:27.240 に答える
0
static void test(Map<Integer, Map<Integer, ? extends Number>> a) { }

これは実際には私にとっては問題なく機能します(JavaSE-1.6)。

于 2012-07-23T00:17:07.687 に答える