2015-12-19 47 views
0

我建立了一個Java類,它接收一個通用對象;編譯器警告關於調用時的原始類型地圖#put()

類唯一字段設置爲:

private Map map = new HashMap<T,Integer>(); 

我的問題是,有些方法的過程中我寫的,當我呼籲HashMap對象和編譯器put方法警告我,diaplay以下消息:

類型安全:方法put(Object, Object)屬於原始類型HashMap。參考通用類型Map<K,V>應參數化

我更喜歡避免編譯器警告,因爲它可能以運行時錯誤結束。

如果你能向我解釋信息,以及我需要做什麼來消除它,我會很高興。

我寫的方法是:

public void addItem(T item) { 
    if (this.map.containsKey(item)) { 
     this.map.put(item, (int)this.map.get(item) + 1); 
    } 
    else { 
     this.map.put(item, 1); 
    } 
} 

,在這裏你能看到的編譯器抱怨:

Code screenshot

+0

我不相信你真的得到了你所說的信息。我相信其實你得到了「類型安全:方法put(Object,Object)屬於原始類型** Map **」。 –

回答

2

變化

private Map map = new HashMap(); 

private Map<Type1, Type2> map = new HashMap<>(); 

其中Type1 & Type2是類名地圖的key & value(分別)

對於例如,聲明地圖String值由Integer小號索引的: (請注意,您不能使用原始類型)

private Map<Integer, String> map = new HashMap<>(); 

您的方法的缺點可以在您的方法的第3行中看到,需要進行羽化。很顯然,如果鍵值對被替換爲不同的值類型,則會導致ClassCastException。 (在這種情況下,你向下轉換到一個int,這是無效的)

通過參數化地圖,則迫使對象的類型爲包含內側(或將要使用的密鑰的類型)

+2

你的回答是正確的,但是恐怕它並沒有真正幫助OP。你給他的魚,而不是給他釣魚竿......我希望*實際答案*真正解釋了他錯誤信息背後的原因。 –

+1

你是對的。我會更新我的答案。 –

0

映射的聲明類型是非參數化接口,編譯器會檢查聲明的類型,而不是實際的類型。

0

如果你要正確地使用仿製藥,它,如果你只在實例中使用它們new HashMap<T,Integer>()(=通過調用new運營商創建一個新的對象),但你也應與仿製藥申報你的變量是不夠的:

private Map<T,Integer> map = new HashMap<T,Integer>(); 

由於Java 7,您不必重複類型的實例,因爲編譯器是足夠聰明的推斷(=推斷)從申報正確的類型。這意味着你可以寫只是

private Map<T,Integer> map = new HashMap<>(); 

建設<>被稱爲基於其形狀的鑽石操作

您的編譯器抱怨使用沒有泛型的Map,這被稱爲原始類型

我相信你沒有正確複製警告信息。我的編譯器說

類型安全:該方法的put(對象,對象)屬於原始類型地圖

通知地圖,而不是HashMap。因爲編譯器不能(通常)知道你分配給map變量的實際實例。因此,編譯器抱怨原始類型的可變map的,而不是繞其實際內容

,編譯器應該已經抱怨在聲明

private Map map = new HashMap<T,Integer>(); 

地圖(除非你在一定程度上將抑制它)是一個原始類型。參考通用類型地圖應參數化

這正是我寫的。從他們出現的第一行開始讀取警告始終是一個好建議。