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)); } }