在使用Gson将json数组解析为List的时候,用到了TypeToken,对于其必须要写成new TypeToken<List<OrderDetail>>() {}
这种形式感到有些不解。
有不解了怎么办
知识不能得过且过,有不解就要去探索。 --我
好了押韵结束,我们一起去探索吧。
为什么不能直接new一个对象
翻了翻Gson的源码

可以看到TypeToken()是protected的,所以不能够直接new一个TypeToken对象,想要调用该类的public方法就只能用他的子类去访问。
此时用匿名类就很合适了,比如这样:
Gson gson = new Gson();
List<Integer> integerList = gson.fromJson(jsonArray, new TypeToken<List<Integer>>() {}.getType();
为什么是protected而不是public
真相渐渐明了,但还有一个困惑,为什么构造方法要写成protected而不是public呢?
因为Java的泛型是「伪泛型」,因为Java类型擦除(type erasure)机制的存在,在编译成字节码的时候,泛型信息会被擦除。
关于类型擦除,引用一下这篇文章中的一段:
Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。
因为Java的这种机制的存在,使得Gson在运行时不能获取到泛型,从而导致反序列化的结果不尽如人意(根本不行)。
TypeToken类中有这样一个方法,如图

通过该方法就能够获取父类的泛型参数,达到精准解析的效果。
网友评论