终于可以开启Retrofit > Type之旅了
从Utils类开始
getRawType
/**
* 获取对象的Type类型所对应的最接近的Class类型
* 1.Type分为Class类型跟四大Type类型
* 2.四大Type类型所对应的Class类型何解?
* 2.1 ParameterizedType :
* List<String> strList 通过 getRawType 获取List Type,再转Class
* 2.2 GenericArrayType :
* List<String>[] strListArray > getGenericComponentType > java.util.List<java.lang.String> 为 ParameterizedType 递归2.1
* 最后Array.newInstance(上一步得到的Class).getClass();(创建此类型的数组对象,再获取其Class)
* 2.3 TypeVariable :
* T extends List & Serializable,因为有多个边界,所以有一个原生类型比拥有一个必要类型更ok,直接返回Object.class
* 2.4 WildcardType :
* ? extends Number ,因为现阶段通配符只接受一个上边界或下边界,所以可以获取边界后再递归getRawType,一般获取边界后直接为Class类型
*
*/
static Class<?> getRawType(Type type) {
if (type == null) throw new NullPointerException("type == null");
if (type instanceof Class<?>) {
// Type is a normal class.
return (Class<?>) type;
}
if (type instanceof ParameterizedType) {// example: List<String>、List<T>
ParameterizedType parameterizedType = (ParameterizedType) type;
// I'm not exactly sure why getRawType() returns Type instead of Class. Neal isn't either but
// suspects some pathological case related to nested classes exists.
Type rawType = parameterizedType.getRawType();// example:List<String> 这里指 List,必定为Class
if (!(rawType instanceof Class)) throw new IllegalArgumentException();
return (Class<?>) rawType;
}
if (type instanceof GenericArrayType) {// example: Class<T>[]、Class<?>[]
// List<String>[] pTypeArr > getGenericComponentType > java.util.List<java.lang.String> 为 ParameterizedType
// T[] vTypeArr > getGenericComponentType > T 为 TypeVariable
Type componentType = ((GenericArrayType) type).getGenericComponentType();// TypeVariable ParameterizedType
// 返回的还是数组类型的类,数组类型的类
return Array.newInstance(getRawType(componentType), 0).getClass();// 先找到数组的类型的class,再通过Array.newInstance去创建此类型的数组对象,再getClass
}
if (type instanceof TypeVariable) {// example: T、T extends Number
// We could use the variable's bounds, but that won't work if there are multiple. Having a raw
// type that's more general than necessary is okay.
// 我们可以是用变量的上边界,但是如果有多个,有一个原生类型比拥有一个必要类型更ok
return Object.class;
}
if (type instanceof WildcardType) {// example: ?、? extends Number 、 ? super Integer、Class[]、String
// 获取上边界,再查看上边界的原生类型
// 现阶段通配符只接受一个上边界或下边界, 返回数组是为了以后的扩展, 实际上现在返回的数组的大小是1
return getRawType(((WildcardType) type).getUpperBounds()[0]);
}
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
+ "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
}
可以看到:
1. 一个Type对象进来,不是Class就是四大Type类型。
2. 可以通过字段的Type类型,获取代码中最接近的Class的类型。
3. ParameterizedType.getRawType为何返回的是Type而不是Class?第一:其返回的不会再是四大Type 之一,必定为Class类型;第二:返回Type而不是Class的原因我觉得应该是为了各方法类型返回的统一;第三:有可能像JakeWharton所说的,猜测可能是类的嵌套会导致一些病理情况;
4. 可以猜测此方法用来获取泛型类型的具体类型,以便对象创建;我们只能通过这种方式在运行期创建最适合的对象,但是代码期并不能清楚实际创建的类型,我们仅仅只能在一个类中使用类型推断获取返回类型,并不太能跨类进行具体类型的代码层传递。
getGenericSupertype
/**
* Returns the generic supertype for {@code supertype}. For example, given a
* class {@code IntegerSet}, the result for when supertype is
* {@code Set.class} is {@code Set<Integer>} and the result when the
* supertype is {@code Collection.class} is {@code Collection<Integer>}.
*
*
* 返回通用超类型。 例如,给定一个类IntegerSet,当超类型为Set.class时的结果为Set <Integer>,
* 当超类型为 Collection.class 时的结果为Collection <Integer>}。
*/
static Type getGenericSupertype(Type context, Class<?> rawType,
Class<?> toResolve) {
if (toResolve == rawType)
return context;
// We skip searching through interfaces if unknown is an interface.
// 如果toResolve是接口(如果不是接口则跳过搜索)
if (toResolve.isInterface()) {
// 判断rawType的接口之一会不会是toResolve
Class<?>[] interfaces = rawType.getInterfaces();
for (int i = 0, length = interfaces.length; i < length; i++) {
if (interfaces[i] == toResolve) {// toResolve是rawType的接口之一
return rawType.getGenericInterfaces()[i];// 逻辑上返回的是toResolve
} else if (toResolve.isAssignableFrom(interfaces[i])) {// toResolve是rawType接口的父接口
return getGenericSupertype(
rawType.getGenericInterfaces()[i], interfaces[i],
toResolve);// 通过rawType父接口类型,父接口,toResolve 继续获取父接口的通用超类(toResolve类型一致的超类)
}
}
}
// Check our supertypes. 检查超类
// 既然toResolve不是rawType的接口,那么会不会是父类之一呢
if (!rawType.isInterface()) {// 如果rawType也不是接口,也就是两个都是普通类
while (rawType != Object.class) {
Class<?> rawSupertype = rawType.getSuperclass();// 直接父类
if (rawSupertype == toResolve) {// 父类正好为toResolve类型
return rawType.getGenericSuperclass();// 获取父类Type
} else if (toResolve.isAssignableFrom(rawSupertype)) {// toResolve是rawSupertype的父类
// 递归获取父类
return getGenericSupertype(rawType.getGenericSuperclass(),
rawSupertype, toResolve);// 通过父类型,父类,toResolve 继续获取父类的通用超类(toResolve类型一致的超类)
}
rawType = rawSupertype;
}
}
// We can't resolve this further.
// 我们不能进一步解决这个类型获取问题
// toResolve 不是 rawType的父类或者父类的父类,也不是rawType接口 或者 父接口的接口(这里我们只能强行使用toResolve)
return toResolve;
}
未完待续…