Java嵌套映射的重复投射
为什么这个演员会工作?
import java.util.HashMap; import java.util.Map; public class TestMap { public static void main(String[] args) { Map<String,Map<String,Integer>>>> resultMap = new HashMap<>(); Map<String,Object> aMap = new HashMap<String,Object>(); Map<String,Integer> hiddenMap = new HashMap<String,Integer>(); hiddenMap.put("fortytwo",42); aMap.put("key",hiddenMap); resultMap = (Map<String,Integer>>>>) aMap.get("key"); System.out.println(resultMap); } } 这个: Map<String,Integer>>>>> resultMap = new HashMap<>(); ... resultMap = (Map<String,Integer>>>>>) aMap.get("key"); 等等… 这是如何发生的隐藏地图是Map< String,Integer>成功转换为Map< String,Map< String,Integer>>>>结果映射? 始终打印: {fortytwo = 42} 这也适用(地图而不是地图): public static void main(String[] args) { Map<String,Integer>>>>> resultMap = new HashMap<>(); Map<String,Map> aMap = new HashMap<String,Map>(); Map<String,Integer>>>>>) aMap.get("key"); System.out.println(resultMap); } 编辑:所以@shizhz说,这是因为类型擦除当然!所以上面的代码相当于: Map resultMap = new HashMap(); Map aMap = new HashMap(); Map hiddenMap = new HashMap(); hiddenMap.put("fortytwo",42); aMap.put("key",hiddenMap); resultMap = (Map) aMap.get("key"); 这也有效 解决方法
因为在编译时使用java泛型来提供更严格的类型检查,所以编译器根据
Type Erasure rules擦除type参数:
>如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或对象.因此,生成的字节码仅包含普通的类,接口和方法. 在代码Map< String,Map> aMap = new HashMap< String,Map>();,aMap中的值是原始类型Map,这意味着当您尝试将原始类型的Map转换为任何泛型类型时,编译器不知道它包含的类型是什么像Map< String,Integer>这样的Map,最好的编译器可以做的就是给你一个警告.泛型类型在编译时被擦除,并且当您从泛型映射获取值时将生成类型转换,因此如果类型不匹配,您只能获得运行时ClassCastException异常. 我们来看看下面的例子: public static void main(String[] args) { Map map = new HashMap(); map.put("hello","world"); map.put(new Integer(1),1); map.put(new Object(),Lists.newArrayList("hello")); Map<String,Integer> m = (Map<String,Integer>) map; System.out.println(m); Integer i = m.get("hello");// ClassCastException happens at here at runtime } 我正在尝试将包含各种键和值的Map转换为Map< String,Integer>但是没有编译错误,在类型擦除之后,上面的代码实际上相当于: public static void main(String[] args) { Map map = new HashMap(); map.put("hello",Lists.newArrayList("hello")); Map m = (Map) map; System.out.println(m); Integer i = (Integer)m.get("hello"); } 现在您可以轻松地告诉为什么最后一行导致了ClassCastException. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |