Gson通过借助TypeToken获取泛型参数的类型的方法

本文探讨了如何利用Google的Gson库处理Java泛型的序列化与反序列化问题,尤其是在运行时获取泛型参数类型的方法。通过分析Class类的getGenericSuperClass方法和ParameterizedType接口的作用,介绍了具体的实现细节。

最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下。

由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型)。

但是有的时候,我们确实需要获知泛型参数的类型,比如将使用了泛型的Java代码序列化或者反序列化的时候,这个时候问题就变得比较棘手。

?
2
4
6
8
class  T value;
}
Gson gson =  Gson();
Foo<Bar> foo =  Foo<Bar>();
gson.toJson(foo);   
gson.fromJson(json, foo.getClass()); 
1
3
5
7
new  t.setValue();
   new  String gStr = GsonUtils.gson.toJson(t,type);
   TestGeneric t1 = GsonUtils.gson.fromJson(gStr, type);
  
1
3
5
7
9
11
13
15
17
class  public public this}
  
  T[] getInstance(){
   (T[])Array.newInstance(kind,  );
  public void Foo<String> foo = Foo(String.);
   }
1
3
5
7
9
11
13
15
abstract  Foo<T>{
  
  public this}
public  void  Foo<String> foo = Foo<String>(){};
    
 
1
3
Type mySuperClass = foo.getClass().getGenericSuperclass();
   0 <code plain"="">System.out.println(type);

 

运行结果是class java.lang.String。

分析一下这段代码,Class类的getGenericSuperClass()方法的注释是:

Returns the Type representing the direct superclass of the entity (class, interface, primitive type or void) represented by thisClass.

If the superclass is a parameterized type, the Type object returned must accurately reflect the actual type parameters used in the source code. The parameterized type representing the superclass is created if it had not been created before. See the declaration of ParameterizedType for the semantics of the creation process for parameterized types. If thisClass represents either theObject class, an interface, a primitive type, or void, then null is returned. If this object represents an array class then theClass object representing theObject class is returned

概括来说就是对于带有泛型的class,返回一个ParameterizedType对象,对于Object、接口和原始类型返回null,对于数 组class则是返回Object.class。ParameterizedType是表示带有泛型参数的类型的Java类型,JDK1.5引入了泛型之 后,Java中所有的Class都实现了Type接口,ParameterizedType则是继承了Type接口,所有包含泛型的Class类都会实现 这个接口。

实际运用中还要考虑比较多的情况,比如获得泛型参数的个数避免数组越界等,具体可以参看Gson中的TypeToken类及ParameterizedTypeImpl类的代码。

posted on 2012-08-01 16:26  brock 阅读(7550)  评论(4)   编辑   收藏

评论

#  re: Gson通过借助TypeToken获取泛型参数的类型的方法[未登录]  2013-01-17 22:38  tao
哥们,你这文章我看不太明白,你这个调用怎么调用可以返回泛型,能不能组织一下弄出一个实例,谢谢   回复   更多评论 
  

#  re: Gson通过借助TypeToken获取泛型参数的类型的方法[未登录]  2013-01-21 14:03  brock
*/
@SuppressWarnings("unchecked")
public static <T> T fromJson(String json, TypeToken<T> token, String datePattern) {
if (StringUtils.isEmpty(json)) {
return null;
}
GsonBuilder builder = new GsonBuilder();
if (StringUtils.isEmpty(datePattern)) {
datePattern = DEFAULT_DATE_PATTERN;
}
builder.setDateFormat(datePattern);

Gson gson = builder.create();
try {
return (T) gson.fromJson(json, token.getType());
} catch (Exception ex) {
ex.printStackTrace();
log.error(json + " 无法转换为 " + token.getRawType().getName() + " 对象!", ex);
return null;
}
}   回复   更多评论 
  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值