1、问题
Java的泛型是编译期擦除,因此反序列化无法直接指定泛型类型:
List<User> list = JsonbBuilder.create().fromJson(json, List<User>.class);
编译不通过,改为List.class
又达不到预期效果。
2、解决办法
jackson的做法:
List<User> list = JsonbBuilder.create().fromJson(json, new TypeReference<List<User>>(){});
johnzon的做法:
List<User> list = JsonbBuilder.create().fromJson(json, new JohnzonCollectionType<List<User>>(){});
genson的做法:
List<User> list = JsonbBuilder.create().fromJson(json, new GenericType<List<User>>(){});
或者使用构造方法传入类型类和泛型类
List<User> list = JsonbBuilder.create().fromJson(json, new JohnzonParameterizedType(List.class, User.class));
注:User.class后面还可以接更多的泛型参数
总结
巧妙之处,Java虽然是泛型擦除,但子类可以拿到父类上的泛型类型。
所以TypeReference
、JohnzonCollectionType
、GenericType
,无一例外都是抽象类,后面接了对大括号,表示是创建了该抽象类的匿名子类的实例,再由实例在运行时获取父类的泛型类型。