2012-04-26 60 views
1

我有一個對象定義如下:泛型通配符的正確使用

protected Map<String, ? extends List<? extends LightGeometry>> geoms=new HashMap<String,List<LightGeometry>>(); 

我嘗試的對象,看起來符合通配符

ArrayList<LightGeometry> points=new ArrayList<LightGeometry>(); 
points.add((LightGeometry)new LightPoint(pt)); 
geoms.put("point", points); 

編譯器插入拋出一個錯誤,指出:

方法put(String, capture#18-of ? extends List<? extends LightGeometry>)類型Map<String,capture#18-of ? extends List<? extends LightGeometry>>不適用於參數(String, ArrayList<LightGeometry>)

我錯過了什麼?

編輯:爲什麼我使用與泛型類型 它基本上可以歸結爲能夠在列表(我通過服務獲得)分配給該geoms對象,它是在另一個類的通配符,沒有必須篩選清單才能投射。

public void onSuccess(Map<String, ArrayList<LightPolygon>> result) { 
    // TODO Auto-generated method stub 
    GWT.log("" + result.size()); 
    Log.debug("" + result.size()); 
    long startTime = System.currentTimeMillis(); 
    if (overlay != null) { 
     overlay.setData(result); 
     overlay.update(); 
     Log.debug("time to add features: " 
       + (System.currentTimeMillis() - startTime)); 
    } 
} 

如果我讓geoms變量Map<String, List<LightGeometry>>然後我得到一個錯誤鑄,說,我不能指定一個Map<String,ArrayList<LightPolygon>>到「地圖>`

+0

我希望能夠在不使用鑄造的情況下插入值 – giscope 2012-04-26 19:32:18

回答

7

一個普通的通配符並不意味着「任何延伸List的東西「它意味着」擴展List的一些特定事物,但我不知道具體是什麼。「

因此,將任何內容添加到集合是非法的,因爲您不知道具體是什麼!它可以是LinkedLists的一個映射,在這裏你將一個ArrayList放入其中,當他們認爲它是一個LinkedList時,會導致其他人得到類轉換異常。

如果你想要一個包含任何類型的列表的地圖,只要將它聲明爲一個列表地圖,而不是地圖?擴展List。

-

TL;博士 - 這你想要做什麼,而不通配符。通配符通常用於指定方法簽名,如果您知道類型是什麼,則無關緊要。如果你只是想要一個包含子類的集合,你只需指定超類型。

例如:

Map<String, List<Number>> map = new HashMap<String,List<Number>>(); 

List<Number> integers =new ArrayList<Number>(); 
integers.add(Integer.valueOf(1)); 
map.put("integers", integers); 

List<Number> floats = new LinkedList<Number>(); 
floats.add(Float.valueOf(5.2f)); 
map.put("floats", floats); 

沒有鑄造!

+1

Java泛型不是協變的,它本質上是非類型安全的。編譯器迫使你進行強制轉換,讓你說「我知道這個集合不再能保證編譯器的類型安全。」如果您不想進行演員表演,您必須將您的列表聲明爲分母列表。 – Affe 2012-04-26 22:11:01

+0

真棒男人..謝謝一堆! – giscope 2012-04-26 22:23:15