fastjson与内部类小记
问题:
json解析java内部类时,在使用fastjson的以下方法,出现了空指针
public static <T> T parSEObject(String text,Class<T> clazz)
场景:
1.java代码有非static修饰的内部类
2.fastjson版本1.2.7
解决:
1将待转换的model里面的内部类用static修饰.2将内部类拿出来
复现:
过程:
1.跟踪源码
最终报错到JavaBeanDeserializer.java:113所以我们从头跟踪到这里就行.
从parSEObject开始,
图中红色为有问题的地方,其它代码不做研究,这个parse是个解析器,封装了配置信息,时间格式,和parseContext(最终是这个报错,但不是这个问题)
进来之后,红色框里面的是个反序列实现,里面最终返回了一个确定反序列子类,这个方法进去之后,debugger最终我们的数据委托给了JavaBeanDeserializer.
转到JavaBeanDeserializer.createInstance方法里面,来到我们出问题的代码,在这之前,并没有发现哪里有初始化context的操作,因此,可以判断问题不是在这,与空指针无关.现在继续走代码到,文章最初飘红的代码,最后研究下这个代码要做什么(因为代码不长,所以截图不会很多,此处没有详细说明)
这时我们发现,代码走的是else条件,也就是说创建的是有参的构造方法,来初始化.
最终,找到问题所在了.
2.整理问题
我们的内部类没有带参的构造方法,为什么这里会出现初始化有参的构造方法?
3.找关联
既然是Constructor这有问题,那么我们看下这个方法的api
英文表示太多不爱看,搜索下关键字inner,发现了一个线索,这个意思大概是说内部类不是static声明的,第一个参数应该是封闭实例,而且给了一个参考章节
看了这个章节的内容,表示不懂,到现在为止,只知道"非静态内部类,持有外部类的一个实例",想一下这个和那个有什么关系呢.(其实到这里,google百度可以解决问题了)
4.求人不如求已
记得以前看过内部类的class文件,所以,现在想去看下class文件构造.
javac Tester.java后,一看目录下面生成了两个文件Testter.class和Testter$Nest.class,idea自带了反编译,我用eclipse打开查看了这两个class文件,终于发现问题了!!
原来内部类是通过构造方法来设置外部类引用的,这样初始化时,必须要传参数才行(再具体的详情请转@朝花夕拾——Java的synthetic修饰词)
5.验证
去了fastjson,发现有人有过这样的问题,随后google搜索了一番,发现原因是正确的.
以上均为个人观点,欢迎指正.