我们使用Gson的时候基本是需要先定义一个数据模型,然后通过一个String流转化为我们OO的对象。那么对于一个框架来说,如何去获得用户想要的数据类型呢?并且我们又要如何通过这种既定的类型来构造出我们需要的对象?或许你的第一反应就是传递一个Clazz进去,然后通过反射的方法来获得我们的实际对象。跟着这个想法我们来实验一下:
public <T>T createObject(Class<T> clazz) {
        try {
            return (T)clazz.newInstance();
        } catch (Exception e) {
            return null;
        }
    }我们知道对于普通类型的对象我们可以通过Gson提供的fromJson(String,Clazz)来直接生成我们OO层的对象:
 public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
    Object object = fromJson(json, (Type) classOfT);
    return Primitives.wrap(classOfT).cast(object);
  }
public class TypeToken<T> {
  final Class<? super T> rawType;
  final Type type;
  final int hashCode;
   @SuppressWarnings("unchecked")
  protected TypeToken() {
    this.type = getSuperclassTypeParameter(getClass());
    this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
    this.hashCode = type.hashCode();
  }
}
/**
   * Returns the type from super class's type parameter in {@link $Gson$Types#canonicalize
   * canonical form}.
   */
  static Type getSuperclassTypeParameter(Class<?> subclass) {
    Type superclass = subclass.getGenericSuperclass();
    if (superclass instanceof Class) {
      throw new RuntimeException("Missing type parameter.");
    }
    ParameterizedType parameterized = (ParameterizedType) superclass;
    return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
  }由于外部不得不采用匿名类的方式来生成TypeToken<?>,因此,你需要获得的泛型类型包含在你的superclass信息中。假如你的匿名类不包含任何的泛式类型,就会抛出一个"Miss type paramter"异常。我们不妨简单定义一个泛式类型来看一下调用getGenericSuperClazz后得到的东西:
public class MySub extends MyGson<List<String>> {}我们执行一个getGenericSuperclass()操作,得到的是一个ParameterizedType 类型的Type。而这个Type包含有你几乎关心的所有类型元数据。包括它的拥有者,它的类名,他的泛型参数。
我们之前提到过任何以$打头的都是Gson提供的静态工具类。canonicalize 方法的目的是规范我们在泛型内的参数,并且转化成Gson自己既定的数据结构。那什么叫做规范呢?我们还是使用MySub类作为例子,我们得到的superclass的type是MyGson<List<String>>,由于它只有一个泛型参数,因此parameterized.getActualTypeArguments()[0]方法调用之后的结果就是List<String>这个Type。或许你很纳闷为什么我们需要一个Type类呢?实际上我们知道类是对象是类的个体,个体的集合可以抽象成为类,那么类型如果作为个体,描述类型的类就是Type。或许你还是一头雾水,不要紧,这并不影响我们对Gson源码的分析,我们跟进到$Gson$Type来看一下它如何结构化我们的类型。
public static Type canonicalize(Type type) {
    if (type instanceof Class) {
      Class<?> c = (Class<?>) type;
      return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c;
    } else if (type instanceof ParameterizedType) {
      ParameterizedType p = (ParameterizedType) type;
      return new ParameterizedTypeImpl(p.getOwnerType(),
          p.getRawType(), p.getActualTypeArguments());
    } else if (type instanceof GenericArrayType) {
      GenericArrayType g = (GenericArrayType) type;
      return new GenericArrayTypeImpl(g.getGenericComponentType());
    } else if (type instanceof WildcardType) {
      WildcardType w = (WildcardType) type;
      return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());
    } else {
      // type is either serializable as-is or unsupported
      return type;
    }
  }关于Type类的继承树的(http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Type.html)。
从上面的代码,我们可以比较清楚的看出,Gson对每一Type都转化为自己的数据结构,原因很简单,因为你无法很直接的获取到jdk内部的接口实现。我们打开一个Type实现类看看:
public ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) {
      // require an owner type if the raw type needs it
      if (rawType instanceof Class<?>) {
        Class<?> rawTypeAsClass = (Class<?>) rawType;
        checkArgument(ownerType != null || rawTypeAsClass.getEnclosingClass() == null);
        checkArgument(ownerType == null || rawTypeAsClass.getEnclosingClass() != null);
      }
      this.ownerType = ownerType == null ? null : canonicalize(ownerType);
      this.rawType = canonicalize(rawType);
      this.typeArguments = typeArguments.clone();
      for (int t = 0; t < this.typeArguments.length; t++) {
        checkNotNull(this.typeArguments[t]);
        checkNotPrimitive(this.typeArguments[t]);
        this.typeArguments[t] = canonicalize(this.typeArguments[t]);
      }
    }
实际上,Gson相当于clone了一便JDK内部的数据类型,差别就在于,这个数据结构可以由Gson框架自己控制。此外,我们可以很清楚的看出Gson内部,采用递归的方式来创建内部数据类型。举个例子来说明:
String gsonValue = "[{name:'非子墨',age:23},{name:'非墨',age:23}]";
        TypeToken typeToken = new TypeToken<User[]>(){};我们通过Gson的TypeToken获得一个User数组类型,那么按照我们之前的分析,它会调用到$Gson$Type的canonicalize方法,由于User[]是一种数据类型,因此它在canonicalize 方法中走的case就是:
 if (type instanceof GenericArrayType) {
      GenericArrayType g = (GenericArrayType) type;
      returnType =  new GenericArrayTypeImpl(g.getGenericComponentType());
    } 我们接着往下走,跟到GenericArrayTypeImpl的内部看看
 public GenericArrayTypeImpl(Type componentType) {
      this.componentType = canonicalize(componentType);
    }我们看到在数组类型,采用递归的方式记录了数据类型中成员的类型数据。之所以要调用canonicalize就是要将它转化为Gson自己的数据类型。通过这种方式,Gson构建出自己的一个类型树,基本就完成了类型的采取。
原文:http://blog.csdn.net/hello__zero/article/details/44201033