首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >java typereference_Java泛型 | Jackson TypeReference获取泛型类型信息「建议收藏」

java typereference_Java泛型 | Jackson TypeReference获取泛型类型信息「建议收藏」

作者头像
全栈程序员站长
发布2022-07-05 19:06:49
发布2022-07-05 19:06:49
3.5K0
举报

大家好,又见面了,我是你们的朋友全栈君。

前言

Jackson是一个比较流行的Json序列化和反序列化框架。本文以Jackson为例介绍TypeReference实现涉及泛型的反序列化,及TypeReference的实现原理。对于获取泛型类型信息的场景,TypeReference是一个可以参考的通用解决方案。

实例

Jackson ObjectMapper的readValue可以将Json字符串反序列化为Java对象。如下例中将[{“id”:null,”name”:” “,”age”:500,”gender”:false,”email”:”email”,”employed”:true,”salary”:10}]反序列化为List类型。

Json字符串:

[{

“id”: null,

“name”: ” “,

“age”: 500,

“gender”: false,

“email”: “email”,

“employed”: true,

“salary”: 10

}]

UserResource实体类:

@Builder

@Data

@NoArgsConstructor

@AllArgsConstructor

public class UserResource {

private UUID id;

private String name;

private int age;

private boolean gender;

private String email;

private boolean employed;

private BigDecimal salary;

}

实现

理想的实现方式

理想的实现方式是告诉ObjectMapper的readValue方法,我要的是List,帮我反序列化成这个类型。

List list = new ObjectMapper().readValue(userResourcesStr, List.class);

现实是编译器告诉你这不行,Cannot select from parameterized type. 也很好理解,Java编译器认为List是Class,而List则不是。

换一种方式实现

既然不能用List.class, 那如果我告诉ObjectMapper的readValue方法,我要的是List类型,但返回值类型是List, 会发生什么呢?

List list = new ObjectMapper().readValue(userResourcesStr, List.class);

这时候倒没有编译错误, 但是会有警告:Unchecked assignment: ‘java.util.List’ to ‘java.util.List’, 显然ObjectMapper并不能反序列化为UserResource类型,而是LinkedHashMap类型。如下图所示:

TypeReference的实现方式

ObjectMapper提供了readValue(String content, TypeReference valueTypeRef)接口,第二个参数为new一个TypeReference的子类实例:new TypeReference>(){}。泛型抽象类TypeReference用于通过子类获取完整的泛型类型信息。

public T readValue(String content, TypeReference valueTypeRef)

List list = new ObjectMapper().readValue(userResourcesStr, new TypeReference>(){});

TypeReference 实现原理

上例中new TypeReference>(){}子类的实例,TypeReference源码部分比较简单,主要逻辑是,通过getClass().getGenericSuperclass()获取父类中的参数化类型(ParameterizedType):

TypeReference主要源码:

protected TypeReference()

{

Type superClass = getClass().getGenericSuperclass();

_type = ((ParameterizedType) superClass).getActualTypeArguments()[0];

}

getGenericSuperclass返回一个Type类型的对象,代表实体(class, interface, primitive type or void)的直接父类,如果父类是参数化类型,则返回的Type对象可准确反映源代码中使用的实际type参数。

Class的genericInfo:

总结Jackson ObjectMapper 提供了TypeReference支持对泛型对象的反序列化;

对于获取泛型类型信息的场景,TypeReference是一个可以参考的通用解决方案。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/149950.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档