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

最近在使用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;
}
}   回复   更多评论 
  

你可能感兴趣的:(Gson通过借助TypeToken获取泛型参数的类型的方法)