fastJSON,使用TypeReference处理复杂的泛型对象

2 篇文章 0 订阅

解析JSON, 并将其转换为对应的数据结构。

例如,简单对象,或者复杂的泛型对象

普通对象直接转换

 A a = JSON.parseObject(str, A.class);

如果是Map带有泛型的对象,直接转换则格式不正确

// 如果需要Map<String, String>
Map a = JSON.parseObject(str, Map.class)
// 结果不是想要的格式

使用 TypeReference

// 可以直接使用
HashMap<String, String> map = JSONObject.parseObject(str, new TypeReference<HashMap<String, String>>(){});


// 其他类型对象
EnjoyResponseDTO<EnjoyPageResponseDataDTO<Long>> result = JSONObject.parseObject(str, new TypeReference<EnjoyResponseDTO<EnjoyPageResponseDataDTO<Long>>>(){});

// 或者type的构造中使用参数
EnjoyResponseDTO<EnjoyPageResponseDataDTO<T>> result = JSONObject.parseObject(str, new TypeReference<EnjoyResponseDTO<EnjoyPageResponseDataDTO<T>>>(Long.class){});
                         

TypeReference 使用的两种方式,有参或者无参

例子: EnjoyResponseDTO<EnjoyPageResponseDataDTO<Long>> result = JSONObject.parseObject(str, new TypeReference<EnjoyResponseDTO<EnjoyPageResponseDataDTO<Long>>>(){});

等价于:EnjoyResponseDTO<EnjoyPageResponseDataDTO<T>> result = JSONObject.parseObject(str, new TypeReference<EnjoyResponseDTO<EnjoyPageResponseDataDTO<T>>>(Long.class){});

上面的 无参 构造方法 里面 获取了 参数泛型 (ParameterizedType),后面的 有参 构造方法 用参数 替换了 参数泛型中是  泛型变量 里面的 内容。

如果参数中有编译时未知的,执行时才知道的泛型(一般是用来继承中使用泛型),则使用有参构造方法就很有必有了,可以在使用有参的构造之前,获取实际的泛型,作为参数构造出TypeReference

如果 T 是 泛型变量 , 没传后面的修饰参数 T 会被识别成 T 的上边界(  根据 T的定义 如果: <T extends Number> T 被识别为Number,如果是<T> T被识别为 Object)

以下示例为运行未知泛型使用方式

public class TestJSON {

	@Test
	public void test() {
		A a = new A();
		Data d = new Data();
		Data d2 = new Data();
		SimpleData<Data, Data> sd = new SimpleData<>();
		sd.data = d;
		sd.data2 = d2;
		String str = JSON.toJSONString(sd);
		System.out.println(str);
		SimpleData<Data, Data> data = a.getData(str);
		System.out.println(data);
	}
}
class A extends B<Data, Data> {
}

abstract class B<T, R> {
	public SimpleData<T, R> getData(String str) {
		/* 此时T未知类型,不能直接使用无参,会导致T类型变成JSONObject */
		return JSON.parseObject(str, new TypeReference<SimpleData<T, R>>(getType(0), getType(1)) {});
	}
	/* 获取泛型的实际类型 */
    protected Type getType(int index) {
        Type superClass = getClass().getGenericSuperclass();
        Type type = ((ParameterizedType) superClass).getActualTypeArguments()[index];
        return type;
    }
}
class Data {
	public String a = "1";
	public String b = "2";
}
/* 带有泛型的数据 */
class SimpleData<T, R> {
	public T data;
	public R data2;
}

 

 

  • 19
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值