问题:
调dubbo接口,传参,结果服务端空指针异常
实际我是传了值的:
Map实际的类型是
Map<Long, Map<Integer, List<String>>> postAttributeMap = null
在tomcat本地文件中我打印日志,发现是传递参数过去的,并不是null
在debug过程中,我发现我的map 中key值是有双引号,但是我声明的对象key是Long型。那么应该就是在fastJson再换为map后,调dubbo接口传参,而服务端反序列化不能成功导致的。
问:既然类型不对,为什么在fastJson转为map时没有报错呢?
答:当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。
在指定了map集合中的类型时,fastJson转换的类型最终是个泛型,所以Map不会报错。
解决问题:
使用 TypeReference 可以明确的指定反序列化的类型,核心的方法是getActualTypeArguments
,此方法可以获取父类真实的泛型类型
new TypeReference<Map<Long, Map<Integer, List<String>>>>(){}创建了一个继承TypeReference<T>的匿名子类,在其构造函数中拿到了泛型对应Type(java.lang.reflect.ParameterizedType)
ParameterizedType是一个记录类型泛型的接口, 继承自Type, 一共三方法:
- Type[] getActualTypeArguments(); //返回泛型类型数组
- Type getRawType(); //返回原始类型Type
- Type getOwnerType(); //返回 Type 对象,表示此类型是其成员之一的类型。
例如 Map<String,String>
对应的ParameterizedType三个方法分别取值如下:
- [class java.lang.String, class java.lang.String]
- interface java.util.Map
- null
这里获取泛型的值有点不好理解,这里有篇参考资料,详情请看。