java为什么使用TypeReference
用途
在使用fastJson时,对于泛型的反序列化很多场景下都会使用到TypeReference,例如:
void testTypeReference() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(9);
list.add(4);
list.add(8);
JSONObject jsonObj = new JSONObject();
jsonObj.put("a", list);
System.out.println(jsonObj);
List<String> list2 = jsonObj.getObject("a", new TypeReference<List<Integer>>(){});
System.out.println(list2);
}
输出
{"a":[1,9,4,8]}
[1, 9, 4, 8]
使用TypeReference可以明确的指定反序列化的类型,具体实现逻辑参考TypeReference的构造函数
protected TypeReference(){
Type superClass = getClass().getGenericSuperclass();
Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
}
this.type = cachedType;
}
解说
其中核心的方法是:getActualTypeArguments,它可以得到父类的反省类型
ParameterizedType是一个记录类型泛型的接口, 继承自Type,一共三方法:
- Type[] getActualTypeArguments(); //返回泛型类型数组
- Type getRawType(); //返回原始类型Type
- Type getOwnerType(); //返回 Type 对象,表示此类型是其成员之一的类型。
例如 Map<String,String> 对应的ParameterizedType三个方法分别取值如下:
- [class java.lang.String, class java.lang.String]
- interface java.util.Map
- null
例证
package JsonLearn; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map; public class TypeReferencBaseLearn {
public static class IntMap extends HashMap<String, Integer> {} void test1() {
IntMap intMap = new IntMap();
System.out.println("getSuperclass:" + intMap.getClass().getSuperclass());
System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass());
Type type = intMap.getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType)type;
for (Type t : p.getActualTypeArguments()) {
System.out.println(t);
}
}
} void test2() {
Map<String, Integer> intMap = new HashMap<>();
System.out.println("\ngetSuperclass:" + intMap.getClass().getSuperclass());
System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass());
Type type = intMap.getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType)type;
for (Type t : p.getActualTypeArguments()) {
System.out.println(t);
}
}
} void test3() {
Map<String, Integer> intMap = new HashMap<String, Integer>(){};
System.out.println("\ngetSuperclass:" + intMap.getClass().getSuperclass());
System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass());
Type type = intMap.getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType)type;
for (Type t : p.getActualTypeArguments()) {
System.out.println(t);
}
}
} public static void main(String[] args) {
TypeReferencBaseLearn obj = new TypeReferencBaseLearn();
obj.test1();
obj.test2();
obj.test3();
}
}
输出
getSuperclass:class java.util.HashMap
getGenericSuperclass:java.util.HashMap<java.lang.String, java.lang.Integer>
class java.lang.String
class java.lang.Integer getSuperclass:class java.util.AbstractMap
getGenericSuperclass:java.util.AbstractMap<K, V>
K
V getSuperclass:class java.util.HashMap
getGenericSuperclass:java.util.HashMap<java.lang.String, java.lang.Integer>
class java.lang.String
class java.lang.Integer
注意区分test3()中的:
Map<String, Integer> intMap = new HashMap<String, Integer>(){};
而不是
Map<String, Integer> intMap = new HashMap<String, Integer>;
后者是test2()
java为什么使用TypeReference的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- java运行时获得泛型类型
引言 众所周知,java泛型最重要的特征是泛型擦除,所有泛型在编译时会转换成Object所以在java中运行时无法获得泛型的类型. 但是其实以上的规则是针对方法的内部变量的,如果是其他形式的泛型其实是 ...
- java分享第十三天(fastjson生成和解析json数据,序列化和反序列化数据)
fastjson简介:Fastjson是一个Java语言编写的高性能功能完善的JSON库.fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jack ...
- JacksonUtils.java
package com.vcredit.framework.utils; import java.io.IOException;import java.util.List; import com.fa ...
- Exception in thread "http-bio-8081-exec-3" java.lang.OutOfMemoryError: PermGen space
前言: 在http://www.cnblogs.com/wql025/p/4865673.html一文中我曾描述这种异常也提供了解决方式,但效果不太理想,现在用本文的方式,效果显著. 目前此项目只能登 ...
- Java json工具类,jackson工具类,ObjectMapper工具类
Java json工具类,jackson工具类,ObjectMapper工具类 >>>>>>>>>>>>>>> ...
- redis在Java web项目的简单应用(转载)
看到一篇关于redis和spring集成的文章,实际测试后,可以.转载以备用.谢谢 亲昵YY! html,body { font-size: 15px } body { font-family: He ...
- Java对象序列化与反序列化一 JSON
Java对象序列化与反序列化一 JSON 1. 依赖库 jackson-all-1.6.1.jar 2. 代码 public class Student { private String nam ...
- JSON 解析工具的封装(Java)
JSON 解析工具的封装(Java) 一直想有一个属于自己的JSON工具,今天终于弄好了..... 1.添加pom依赖包 <!--json解析--> <dependency> ...
随机推荐
- javascript 减少全部变量
方法1 自创建一个唯一的全局变量a,把自己用到的变量都加在a上 方法2:模块 String.method('test1', function(){ var a = '12'; return funct ...
- mysql变更数据的捕获和入库
问题:涉及状态的信息,mysql中是update的,缺少中间状态的记录.数据分析中需要这部分数据. 思路:后端服务通过监控某张表的某个字段,根据mysql的binlog文件,还原数据,发送到kafka ...
- poj2828 线段树单点更新
Buy Tickets Time Limit: 4000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java ...
- Nginx 实现端口转发
https://www.cnblogs.com/zhaoyingjie/p/7248678.html Nginx 实现端口转发 什么是端口转发 当我们在服务器上搭建一个图书以及一个电影的应用,其中图书 ...
- 20164317 《网络对抗技术》Exp6 信息搜集与漏洞扫描
Exp6 信息搜集与漏洞扫描 一.原理与实践说明 (1)实践原理 信息搜集:渗透测试中首先要做的重要事项之一,搜集关于目标机器的一切信息 间接收集 DNS记录扫描和枚举 CorpWatch:auxil ...
- jdk在Linux下的安装
之前学linux的时候,也是赶鸭子上架,照着教程一步一步的走,但是今天linux出现了点问题重装一下 重新学习一些linux下常需软件的安装 一般我们再装完系统后,装的匆忙,先把ip搞出来 切换到该目 ...
- ReactNatvie遇到的错误
1:新版的React包中没有包含PropTypes,如果使用需要从‘prop-types’包中导入. 2: 'prop-types'包中直接定义‘PropTypes.style’是无效的,需要使用‘P ...
- Spring Boot中使用Redis数据库
引入依赖 Spring Boot提供的数据访问框架Spring Data Redis基于Jedis.可以通过引入spring-boot-starter-redis来配置依赖关系. <depend ...
- Windows Service 项目中 Entity Framework 无法加载的问题
Windows Service 项目引用了别的类库项目,别的项目用到了 Entity Framework(通过Nuget引入),但是我的 Windows Service 无法开启,于是我修改了 App ...
- select2插件使用小记2 - 多选联动 - 笔记
这是select2插件使用的第二篇,可参考第一篇 select2插件使用小记.上一篇主要是关于基本的使用,这篇主要是关于多选,及联动的.侧重点不同. 效果图如下: 遵从W3C标准:结构.样式.行为.以 ...