Gson源码之Type和TypeToken

Type

  • 1.定义

       是Java中所有类型的公共高级接口,代表了Java中的所有类型 
    
  • 2.类型体系

       数组类型(GenericArrayType)       	例如泛型数组 T[]
       参数化类型(ParamterizedType)        例如list/map
       类型变量(TypeVariable)              
       通配符类型(WildcardType)          	例如 <?>.  <? extend T>
       原始类型(class)                  	 例如 类/接口/枚举/数组
       基本类型(class)                     例如Java中的基本数据类型                       
    
  • 3.Type源码

       public interface Type {
       
       
           /**
            * 返回描述此类型的字符串,包括关于任何类型参数的信息。
            * @return
            */
           default String getTypeName() {
               return toString();
           }
      	}
    
  • 4.ParameterizedType源码

      public interface ParameterizedType extends Type {
          // 返回确切的泛型参数, 如Map<String, Integer>返回[String, Integer]
          Type[] getActualTypeArguments();
      
          //返回当前class或interface声明的类型, 如List<?>返回List
          Type getRawType();
      
          //返回所属类型. 如,当前类型为O<T>.I<S>, 则返回O<T>. 顶级类型将返回null
          Type getOwnerType();
    	}
    

TypeToken

  • 1.它是一个泛型类,通过该类可以获取客户端定义的自定义类型,也就是通过该类,可以获取到java bean的真实类型

  • 2 我们可以通过继承明确其泛型类型;也可以通过传递自定义类型的type来获取泛型的真实类型

          getClass().            返回class对象
          getSuperClass()        返回直接父类的class,不包含泛型
          getGenericSuperclass   返回直接父类的type 包含泛型参数
          getActualTypeArguments 返回运行时的泛型类型
          
          isAssignableFrom   	从类的继承角度来判断,判断是否为某个类的子类
          instanceOf.    	    从实例继承的角度来判断,判断是否为某个类的子类
    
  • 3.源码

      public class TypeToken<T> {
         final Class<? super T> rawType;
         final Type type;
         final int hashCode;
    
     
      
         @SuppressWarnings("unchecked")
         protected TypeToken() {
             //获取typetoken的泛型类型
             this.type = getSuperclassTypeParameter(getClass());
             System.out.println("返回typetoken的泛型类型:"+type);
             //返回泛型类型的class
             this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
             System.out.println("返回class/interface声明的类型:"+rawType);
             //获取type的hashcpde
             this.hashCode = type.hashCode();
             System.out.println("获取泛型类型的hashcode:"+hashCode);
         }
     
      
     
         /**
          * 不安全的
          * @param type
          */
         @SuppressWarnings("unchecked")
         TypeToken(Type type) {
             this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));
             System.out.println("有参数构造之类型type:"+type);
             this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);
             System.out.println("有参数构造之类型rawtype:"+rawType);
             this.hashCode = this.type.hashCode();
             System.out.println("有参数构造之类型hashtype:"+hashCode);
     
         }
     
     
         /**
          * getclass               返回class对象
          * getSuperclass          返回直接父类的class  不包含泛型参数
          * getGenericSuperclass   返回直接父类的type   包含泛型参数
          * getActualTypeArguments 返回运行时的泛型类型
          * @param subclass
          * @return
          */
         static Type getSuperclassTypeParameter(Class<?> subclass) {
             System.out.println("getclass:"+subclass);
     
             //返回直接父类的type
             Type superclass = subclass.getGenericSuperclass();
             //getGenericSuperclass:返回直接父类带泛型类型class com.example.gson.souceCode.TypeToken$1 返回匿名内部类
             System.out.println("getGenericSuperclass:"+superclass);
     
             //若只是class类型 则直接抛异常
             if (superclass instanceof Class) {
                 throw new RuntimeException("Missing type parameter.");
             }
             //转换为ParameterizedType
             ParameterizedType parameterized = (ParameterizedType) superclass;
             System.out.println("ParameterizedType:getActualTypeArguments:"+parameterized.getActualTypeArguments()[0]+"\n getRawType:"
                     +parameterized.getRawType()+"\n toString"+parameterized.toString()+"\n getOwnerType:"+parameterized.getOwnerType());
     
             //获取运行期的泛型类型
             return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
         }
     
         /**
          * 返回此类型的原始(非泛型)类型。
          */
         public final Class<? super T> getRawType() {
             return rawType;
         }
     
         /**
          * 返回泛型类型
          */
         public final Type getType() {
             return type;
         }
     
     
         /**
          * isAssignableFrom  从类的继承角度来判断   判断是否为某个类的父类
          * instanceof        从实例继承的角度来判断   判断是否是某个类的子类
          * @param cls
          * @return
          */
         @Deprecated
         public boolean isAssignableFrom(Class<?> cls) {
             return isAssignableFrom((Type) cls);
         }
     
         /**
          * Check if this type is assignable from the given Type.
          *
          * @deprecated this implementation may be inconsistent with javac for types
          *     with wildcards.
          */
         @Deprecated
         public boolean  isAssignableFrom(Type from) {
             //若type为空 则返回false
             if (from == null) {
                 return false;
             }
             //若对象的引用相同则返回true
             if (type.equals(from)) {
                 return true;
             }
     
             //
             if (type instanceof Class<?>) {//泛型类型
                 return rawType.isAssignableFrom($Gson$Types.getRawType(from));
             } else if (type instanceof ParameterizedType) {//参数化类型
                 return isAssignableFrom(from, (ParameterizedType) type,
                         new HashMap<String, Type>());
             } else if (type instanceof GenericArrayType) {//数组类型
                 return rawType.isAssignableFrom($Gson$Types.getRawType(from))
                         && isAssignableFrom(from, (GenericArrayType) type);
             } else {
                 throw buildUnexpectedTypeError(
                         type, Class.class, ParameterizedType.class, GenericArrayType.class);
             }
         }
     
         /**
          * Check if this type is assignable from the given type token.
          *
          * @deprecated this implementation may be inconsistent with javac for types
          *     with wildcards.
          */
         @Deprecated
         public boolean isAssignableFrom(com.google.gson.reflect.TypeToken<?> token) {
             return isAssignableFrom(token.getType());
         }
     
         /**
          * Private helper function that performs some assignability checks for
          * the provided GenericArrayType.
          */
         private static boolean isAssignableFrom(Type from, GenericArrayType to) {
             Type toGenericComponentType = to.getGenericComponentType();
             if (toGenericComponentType instanceof ParameterizedType) {
                 Type t = from;
                 if (from instanceof GenericArrayType) {
                     t = ((GenericArrayType) from).getGenericComponentType();
                 } else if (from instanceof Class<?>) {
                     Class<?> classType = (Class<?>) from;
                     while (classType.isArray()) {
                         classType = classType.getComponentType();
                     }
                     t = classType;
                 }
                 return isAssignableFrom(t, (ParameterizedType) toGenericComponentType,
                         new HashMap<String, Type>());
             }
             // No generic defined on "to"; therefore, return true and let other
             // checks determine assignability
             return true;
         }
     
         /**
          * Private recursive helper function to actually do the type-safe checking
          * of assignability.
          */
         private static boolean isAssignableFrom(Type from, ParameterizedType to,
                                                 Map<String, Type> typeVarMap) {
     
             if (from == null) {
                 return false;
             }
     
             if (to.equals(from)) {
                 return true;
             }
     
             // First figure out the class and any type information.
             Class<?> clazz = $Gson$Types.getRawType(from);
             ParameterizedType ptype = null;
             if (from instanceof ParameterizedType) {
                 ptype = (ParameterizedType) from;
             }
     
             // Load up parameterized variable info if it was parameterized.
             if (ptype != null) {
                 Type[] tArgs = ptype.getActualTypeArguments();
                 TypeVariable<?>[] tParams = clazz.getTypeParameters();
                 for (int i = 0; i < tArgs.length; i++) {
                     Type arg = tArgs[i];
                     TypeVariable<?> var = tParams[i];
                     while (arg instanceof TypeVariable<?>) {
                         TypeVariable<?> v = (TypeVariable<?>) arg;
                         arg = typeVarMap.get(v.getName());
                     }
                     typeVarMap.put(var.getName(), arg);
                 }
     
                 // check if they are equivalent under our current mapping.
                 if (typeEquals(ptype, to, typeVarMap)) {
                     return true;
                 }
             }
     
             for (Type itype : clazz.getGenericInterfaces()) {
                 if (isAssignableFrom(itype, to, new HashMap<String, Type>(typeVarMap))) {
                     return true;
                 }
             }
     
             // Interfaces didn't work, try the superclass.
             Type sType = clazz.getGenericSuperclass();
             return isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap));
         }
     
         /**
          * Checks if two parameterized types are exactly equal, under the variable
          * replacement described in the typeVarMap.
          */
         private static boolean typeEquals(ParameterizedType from,
                                           ParameterizedType to, Map<String, Type> typeVarMap) {
             if (from.getRawType().equals(to.getRawType())) {
                 Type[] fromArgs = from.getActualTypeArguments();
                 Type[] toArgs = to.getActualTypeArguments();
                 for (int i = 0; i < fromArgs.length; i++) {
                     if (!matches(fromArgs[i], toArgs[i], typeVarMap)) {
                         return false;
                     }
                 }
                 return true;
             }
             return false;
         }
     
         private static AssertionError buildUnexpectedTypeError(
                 Type token, Class<?>... expected) {
     
             // Build exception message
             StringBuilder exceptionMessage =
                     new StringBuilder("Unexpected type. Expected one of: ");
             for (Class<?> clazz : expected) {
                 exceptionMessage.append(clazz.getName()).append(", ");
             }
             exceptionMessage.append("but got: ").append(token.getClass().getName())
                     .append(", for type token: ").append(token.toString()).append('.');
     
             return new AssertionError(exceptionMessage.toString());
         }
     
         /**
          * Checks if two types are the same or are equivalent under a variable mapping
          * given in the type map that was provided.
          */
         private static boolean matches(Type from, Type to, Map<String, Type> typeMap) {
             return to.equals(from)
                     || (from instanceof TypeVariable
                     && to.equals(typeMap.get(((TypeVariable<?>) from).getName())));
     
         }
     
         @Override public final int hashCode() {
             return this.hashCode;
         }
     
         @Override public final boolean equals(Object o) {
             return o instanceof  TypeToken<?>
                     && $Gson$Types.equals(type, ((TypeToken<?>) o).type);
         }
     
         @Override public final String toString() {
             return $Gson$Types.typeToString(type);
         }
     
     
         /**
          * 传递一个type返回一个泛型是object的TypeToken
          * @param type
          * @return
          */
         public static  TypeToken<?> get(Type type) {
             return new  TypeToken<Object>(type);
         }
     
         /**
          * 传递一个type返回一个泛型是T的TypeToken
          * @param type
          * @return
          */
         public static <T>  TypeToken<T> get(Class<T> type) {
             return new  TypeToken<T>(type);
         }
     
         /**
          * 传递一个type返回一个泛型是T的TypeToken
          * @param
          * @return
          */
         public static  TypeToken<?> getParameterized(Type rawType, Type... typeArguments) {
             return new TypeToken<Object>($Gson$Types.newParameterizedTypeWithOwner(null, rawType, typeArguments));
         }
     
         /**
          * Gets type literal for the array type whose elements are all instances of {@code componentType}.
          */
         public static  TypeToken<?> getArray(Type componentType) {
             return new  TypeToken<Object>($Gson$Types.arrayOf(componentType));
     }
     	}
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值