JSON 序列化与反序列化(二)使用TypeReference 构建类型安全的异构容器
1. 泛型通常用于集合,如Set和Map等。这样的用法也就限制了每个容器只能有固定数目的类型参数,一般来说,这也确实是我们想要的。
然而有的时候我们需要更多的灵活性,如数据库可以用任意多的Column,如果能以类型安全的方式访问所有Columns就好了,幸运的是
有一种方法可以很容易的做到这一点,就是将key进行参数化,见以下代码
public class Favorites {
private Map<Class<?>, Object> favorites = new HashMap<Class<?>, Object>();
public <T> void setFavorite(Class<T> klass, T thing) {
favorites.put(klass, thing);
}
public <T> T getFavorite(Class<T> klass) {
return klass.cast(favorites.get(klass));
}
public static void main(String[] args) {
Favorites f = new Favorites();
f.setFavorite(String.class, "Java");
f.setFavorite(Integer.class, 0xcafebabe);
String s = f.getFavorite(String.class);
int i = f.getFavorite(Integer.class);
}
}
2.不足之处
There is a limitation to this pattern.
//You can't add your favorite List<String> to a Favorites because you simply can't make a type token for a generic type.
f.setFavorite(List<String>.class, Collections.emptyList());
3.改进
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List; /**
* References a generic type.
*
* @author crazybob@google.com (Bob Lee)
*/
public abstract class TypeReference<T> { private final Type type;
private volatile Constructor<?> constructor; protected TypeReference() {
Type superclass = getClass().getGenericSuperclass();
if (superclass instanceof Class) {
throw new RuntimeException("Missing type parameter.");
}
this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
} /**
* Instantiates a new instance of {@code T} using the default, no-arg
* constructor.
*/
@SuppressWarnings("unchecked")
public T newInstance()
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException {
if (constructor == null) {
Class<?> rawType = type instanceof Class<?>
? (Class<?>) type
: (Class<?>) ((ParameterizedType) type).getRawType();
constructor = rawType.getConstructor();
}
return (T) constructor.newInstance();
} /**
* Gets the referenced type.
*/
public Type getType() {
return this.type;
} public static void main(String[] args) throws Exception {
List<String> l1 = new TypeReference<ArrayList<String>>() {}.newInstance();
List l2 = new TypeReference<ArrayList>() {}.newInstance();
}
}
参考:
- com.google.common.reflect.TypeToken<T>
- com.fasterxml.jackson.core.type.TypeReference
JSON 序列化与反序列化(二)使用TypeReference 构建类型安全的异构容器的更多相关文章
- Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全 Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...
- 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变
在net中json序列化与反序列化 准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则 ...
- Jaskson精讲第7篇-类继承关系下的JSON序列化与反序列化JsonTypeInfo
Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的, ...
- Newtonsoft.Json 序列化和反序列化 时间格式
From : http://www.cnblogs.com/litian/p/3870975.html 1.JSON序列化 string JsonStr= JsonConvert.SerializeO ...
- Newtonsoft.Json 序列化和反序列化 时间格式 [转]
1.JSON序列化 string JsonStr= JsonConvert.SerializeObject(Entity); eg: A a=new A(); a.Name="Elain ...
- C# JSON 序列化和反序列化——JavaScriptSerializer实现
一. JavaScriptSerializer 类由异步通信层内部使用,用于序列化和反序列化在浏览器和 Web 服务器之间传递的数据.您无法访问序列化程序的此实例.但是,此类公开了公共 API.因此, ...
- 序列化对象C++对象的JSON序列化与反序列化探索
新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正 一:背景 作为一名C++开发人员,我始终很期待能够像C#与JAVA那样,可以省力的进行对象的序列化与反序列化,但到现在为止,还没有找 ...
- C++对象的JSON序列化与反序列化探索
一:背景 作为一名C++开发人员,我一直很期待能够像C#与JAVA那样,可以轻松的进行对象的序列化与反序列化,但到目前为止,尚未找到相对完美的解决方案. 本文旨在抛砖引玉,期待有更好的解决方案:同时向 ...
- 迄今为止 .Net 平台功能最强大,性能最佳的 JSON 序列化和反序列化库。
Swifter.Json 这是迄今为止 .Net 平台功能最强大,性能最佳的 JSON 序列化和反序列化库. Github : https://github.com/Dogwei/Swifter.Js ...
随机推荐
- Linux kernel 之 kobject
总听有人说 Linux kernel 拥有一团无比巨大看似杂乱无章其实有迹可循的链表,今天参考一下其他大牛的相关资料记录一下. kset 结构体 151 /** 152 * struct kset - ...
- js学习笔记24----焦点事件
事件: onfous : 元素获取焦点时触发事件 onblur : 元素失去焦点时触发事件 方法: obj.focus(); 可指定元素设置焦点 obj.blur(); 取消指定元素的焦点 obj.s ...
- C++ c++与C语言的区别(空结构体)
//区别⑨:空结构体声明(C++版本) #include<iostream> using namespace std; struct A{}; class B{}; void main() ...
- SpringCloud架构设计
最近一直在针对SpringCloud框架做项目,从中踩了不少的坑,也渐渐梳理出了一些内容,由于SpringCloud作为一个全家桶,其中东西太多,所以这时候就要有所取舍,这里就想把自己比较常用组件及架 ...
- 下列哪个为JSP的小脚本的标签?(选择1项)
下列哪个为JSP的小脚本的标签?(选择1项) A.<% %> B.<@ %> C.<%! %> D.<%– %> 解答:A
- java---正则表达式的字符串简单实用及扩展链接
一:什么是正则表达式 1.定义:正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查找文字主体时待匹配的 ...
- erlang的进程池。
转自: http://blog.sina.com.cn/s/blog_96b8a1540101542m.html 主要组成部分: https://github.com/devinus/poolboy ...
- No mysqld or mysql.server after mariadb-server install
To start MariaDB on Fedora 20, execute the following command: systemctl start mariadb.service To aut ...
- LPCTSTR —— 摘自百度百科
LPCTSTR用来表示字符是否使用UNICODE. 如果程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串. 类型理解:L,表示 ...
- 电脑端与iPad 端如何共享ChemDraw结构
在日常生活中,我们使用的电脑会有好几种系统,很多的软件不能做好各个系统的兼容.但是ChemDraw软件很好的解决了这个问题,可以应用于Mac.Windows两个电脑客户端以及Chem3D for iP ...