Java 8中Map<String, ? extends Object>转Map<String, Object>的问题咨询
为什么强制转换
Map<String, ? extends Object>到Map<String, Object>会有警告? 首先得说,你的直觉没错——从单个元素来看,? extends Object的所有类型确实都是Object的子类,读取元素时完全可以当作Object来用。但编译器给你警告,是因为泛型本身是不变的,Map<String, ? extends Object>和Map<String, Object>并不是兼容的父子类型。
举个实际的例子就懂了:假设原来的Map其实是Map<String, String>(它符合Map<String, ? extends Object>的定义),如果你把它强制转成Map<String, Object>,之后你可能会不小心往里面塞一个Integer进去。但原来的Map本质上只能存String,这时候后续代码如果把这个Map当作Map<String, String>来用,就会抛出ClassCastException,完全破坏了类型安全。
编译器没办法提前知道你会不会做这种写入操作,所以它只能给你一个未检查转换的警告,提醒你这里可能有潜在风险。
简洁的解决方案
根据你的使用场景,有几种选择:
- 如果只是读取Map,不写入:那根本不用转换,直接用
Map<String, ? extends Object>就好。读取出来的元素本身就是Object类型,完全满足需求,还不会有任何警告。 - 必须转成
Map<String, Object>且能保证不写入非法元素:可以用@SuppressWarnings("unchecked")注解来抑制警告,但一定要确保后续代码不会往这个Map里添加原类型不支持的元素(比如原Map是Map<String, Integer>,就别往里面塞String)。示例:@SuppressWarnings("unchecked") Map<String, Object> safeMap = (Map<String, Object>) originalMap; - 需要安全写入任意Object类型元素:最稳妥的方式是创建一个新的
Map<String, Object>,把原Map的元素复制进去。这样新Map的泛型是完全合法的,你可以放心写入任何Object子类,也不会有警告:Map<String, ? extends Object> originalMap = ...; Map<String, Object> newMap = new HashMap<>(originalMap);
内容的提问来源于stack exchange,提问作者Antonin
相关产品推荐
相关产品推荐

