今天,我發現一個能夠put
的對象在一個現有的Map
中即使對象不能被轉換爲正確的類型。在初始化的Map中放置不一致類型的對象 - 預期的和合法的?
首先,讓我先用一個簡單的例子:
Map<Integer, String> myMap = new HashMap<>(); //plain old hashmap
myMap.put(9,"star"); //no problem
myMap.put(10, 1.2); //Incompatible type, the compiler yells
Map<Integer, Double> aMap = (Map<Integer, Double>) myMap; //Cannot cast, the compiler yells
到目前爲止,一切都在意料之中的,因爲你應該不能夠把不一致類型的對象爲已構建的地圖。現在讓我們來看看這個:
public class NoRulesForMe {
static Object theRing;
public static void main(String[] args){
Map<Integer, String> myMap = new HashMap<>();
myMap.put(9,"star");
Map<Integer, Double> myMapMorphed = castWildly(myMap);
myMapMorphed.put(99, 3.14);
System.out.println(myMapMorphed.get(9)); //"star", as we put in
System.out.println(myMapMorphed.get(99)); //3.14, as we put in
}
public static <T> T castWildly(Object value){
theRing = value;
T morphed = (T) theRing;
return morphed;
}
}
我很驚訝,這並沒有導致運行時錯誤 - 如何地圖實現這一目標,並且是在JLS或API指定了此行爲,因此可以被信賴的?
我想問的原因是我在生產代碼中看到了一個(更多參與的)版本,並且我懷疑,即使這可能是混亂和臭味,它是否可以保證以功能方式工作。任何輸入將不勝感激。
你需要谷歌「鍵入擦除」。 –
這在Java的泛型實現中是_inherent_。 –
@LouisWasserman您可否詳細說明* Java的泛型中固有的*是什麼?編譯器沒有抱怨,我並不感到驚訝。但是我認爲更大的問題是Java如何允許「Double」可以存儲爲「String」。 – flow2k