今天在使用PowerMock进行代码测试用例编写的时候,需要新建一个map,当时脑一抽,写成了:
Map<String, Object> testMap = new HashMap().put("a", "b");
然后收到了IDE的友善提醒:
Incompatible types.
Required: java.util.Map<java.lang.String, java.lang.Object>
Found: java.lang.Object
习惯了接受IDE的建议,当时想都没想,看也没看,就直接Alt + Enter
对代码进行了修改,然后编译器帮我改成了:
Map<String, Object> testMap = (Map<String, Object>) new HashMap<>().put("a", "b");
并顺带提醒:Cast to 'java.util.Map<java.lang.String, java.lang.Object>'
。
我继续欢快地写着测试,最后一运行,test error。
gg
看了看报错原因,我希望得到的是我刚刚新建的testMap,结果得到的却是null。
最后debug了一下,发现被测试的代码逻辑并没有问题,问题的症结在我新建出来的testMap被我给初始化成了null……
回头看我的代码,一开始写的是Map<String, Object> testMap = new HashMap().put("a", "b");
,则testMap被初始化成了put(K, V)的返回值。put接口描述如下:
put
public V put(K key, V value)
在此映射中关联指定值与指定键。如果该映射以前包含了一个该键的映射关系,则旧值被替换。
指定者:
接口 Map<K,V> 中的 put
覆盖:
类 AbstractMap<K,V> 中的 put
参数:
key - 指定值将要关联的键
value - 指定键将要关联的值
返回:
与 key 关联的旧值;如果 key 没有任何映射关系,则返回 null。(返回 null 还可能表示该映射之前将 null 与 key 关联。)
很明显,new HashMap().put("a", "b")
返回的根本就不是一个map,而是put的返回值,V。这里的K是String,而V是Object,因此返回的是一个Object。再结合前面的Map
Map<String, Object> testMap = null;
尴尬……
脑抽一时爽,debug火葬场……
如果想新建map的时候初始化,可以使用匿名内部类:
扫描二维码关注公众号,回复:
1594156 查看本文章
Map map = new HashMap() {
{
put("Name", "puppylpg");
}
};
或者使用Collections和Arrays去初始化集合框架:
List<String> keys = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList("hello@world", "good@bye", "love@you")));