2012-06-14 56 views
0

我的Java應用程序顯示一些奇怪的行爲,並且在找到解決方案時遇到問題。爲什麼Java在讀取LinkedHashMap時自動從字符串轉換爲整數

此代碼片段獲取LinkedHashMap的內容,其中的鍵和值都是String類型,並將它們寫入文本文件。 configWriter類型爲PrintWriter

for (Map.Entry<String, String> entry : configMap.entireSet()) { 

    configWriter.println(entry.getKey() + "=" + entry.getValue()); 
} 

地圖被宣佈:

LinkedHashMap<String, String> configMap = new LinkedHashMap<String, String>(); 

它是通過使用Scanner類從一個文本文件中讀取的標記填充。

一個在地圖中值是String只包含數字(整數),但是當循環到達此值時,它拋出一個ClassCastException說,你可以不投從IntegerString。這非常合理,但值的類型是String。

有沒有辦法強制Java將這個值保持爲String

+9

你可以顯示'configMap'的聲明嗎?這聽起來像是在某處使用了rawtypes,而map並不包含所有的'String's。 –

+3

另外,堆棧跟蹤可能會有所幫助。 –

+1

編輯問題,請勿將信息添加爲評論。 –

回答

7

幾乎可以肯定的是,rawtypes正在某處使用,並且有一個Integer潛入地圖中。

識別其中Integer是越來越插入地圖,以取代的configMap初始化最簡單的方法

Map<String, String> configMap = Collections.checkedMap(
    new LinkedHashMap<String, String>(), String.class, String.class); 

如果不是String其他的東西都會被放入將實際拋出一個異常地圖。我不會親自在生產代碼中使用它,但這可能是「吸出」錯誤的最簡單方法;你會得到一個異常和堆棧跟蹤,確切地說Integer正在插入。

現在,通用類型擦除實現的泛型方式意味着什麼也沒有實際上停止非String值插入到映射中。編譯器做了一些努力來阻止它,但rawtypes和遺留代碼可以繞過它。不過,使用Collections.checkedMap會強制解決該問題。

+0

你是不是指'Collections.checkedMap'? –

+0

...是的。是的,我做到了。太多的番石榴在大腦上。 –

2

Louis Wasserman已經解釋了您的問題的可能原因。

我只想指出你的問題在你的思維中存在一些缺陷。

爲什麼Java的自動串鑄造讀LinkedHashMap的

首先何時整數,你不能從一個String強制轉換爲Integer。對於Java引用類型,如果對象是該類型的實例或該類型的子類型,則只能將對象轉換爲類型。 String類型不是Integer的子類型,因此JVM的操作語義禁止這樣的轉換 - 如果您編寫了試圖執行此操作的可編譯代碼,則會得到運行時異常。

其次,沒有什麼LinkedHashMap ......或任何其他集合類,它會從轉換String一個元/鍵/值實例Integer沒有你告訴它。行爲良好的(Java)API不會做那種事情。

這使我們回到了路易斯的診斷 - 某些東西(例如您的代碼)已將Integer對象添加爲值。如果您使用原始類型或禁止/忽略「未檢查轉換」警告,則會發生這種情況。

相關問題