我試圖寫一個通用的函數將接受以下兩個數據類型對地圖的地圖在Java中
Map <Integer, Map<Integer, Long>>
Map <Integer, Map<Integer, Double>>
我的功能看起來是這樣的,
function(Map<Integer, Map<Integer, ? extends Number>> arg) {}
但我我得到一個不兼容的類型錯誤。它適用於地圖,但不適用於地圖地圖。我無法理解爲什麼?有沒有辦法做到這一點?
我試圖寫一個通用的函數將接受以下兩個數據類型對地圖的地圖在Java中
Map <Integer, Map<Integer, Long>>
Map <Integer, Map<Integer, Double>>
我的功能看起來是這樣的,
function(Map<Integer, Map<Integer, ? extends Number>> arg) {}
但我我得到一個不兼容的類型錯誤。它適用於地圖,但不適用於地圖地圖。我無法理解爲什麼?有沒有辦法做到這一點?
首先讓我們通過使用Set
!而非減少的問題:
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>
的原因是generics are not covariant。編譯器會阻止您將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) { }
你可以嘗試像
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
}
爲什麼不只是參數的方法?
public <T extends Number> void function(Map<Integer, Map<Integer, T>>) { ... }
我發現通配符捕獲容易讓人們誤解它的真實含義。
Map<Integer, ? extends Number>
確實是指任何Map
,其關鍵是Integer
,其值是從Number
派生的類型。這意味着Map<Integer, Integer>,
Map<Integer,Long>
。
因爲這個原因,你永遠不可能真的添加到這些集合中,因爲通配符編譯器不能告訴真實類型是爲了添加。
static void test(Map<Integer, Map<Integer, ? extends Number>> a) { }
這實際上對我來說工作得很好(JavaSE-1.6)。
甜。有用。有什麼地方可以閱讀爲什麼我的功能不起作用嗎? :) – Blacklabel 2012-07-23 00:14:38