Java Type技术笔录

一、吐槽

想必很多人都玩过Java反射,对于类而言大家都有不同的认知和理解,那么什么是Type呢?

 

二、UML

Java Type技术笔录_第1张图片 Type的演化
  • java.lang.reflect

Type:所有类型的基础接口;

ParameterizedType:参数化泛型接口,如List这一整坨;

-> 实现类: ParameterizedTypeImpl

TypeVariable:自定义泛型接口,如List中的T,没有明确指明是什么类或接口,可被方法或者类创建或者调用时决定;

-> 实现类: TypeVariableImpl

WildcardType:通配符泛型接口,如List、List等中的?,没有明确指明范型类型;

-> 实现类: WildcardTypeImpl

GenericArrayType:数组泛型接口,如List[]、T[]等,由泛型构成的数组类型。

-> 实现类: GenericArrayTypeImpl

 

  • java.lang

Class: 实现了Type接口,已家喻户晓,^ ^。

 

三、常用获取Type API

  • java.lang.Class

1、Type[] getGenericInterfaces()

描述: 返回值是Type数组,Type类型为Class或ParameterizedType子类类型,取决于实现的接口指定的泛型;

 

2、Type getGenericSuperclass()

描述: 返回值是Type,Type类型为Class或ParameterizedType子类类型,取决于实现的接口指定的泛型;

 

3、TypeVariable>[] getTypeParameters()

描述: 返回值是类型变量数组,当定义的Class是泛型类时数组才有对应的类型变量元素,否则返回长度为0的数组;

 

  • java.lang.reflect.Field

Type getGenericType()

描述: 返回值是Type,Type类型可为Class、ParameterizedType(如:成员变量 List)、TypeVariable(如:成员变量 T)、GenericArrayType(如:成员变量 T[])

 

  • java.lang.reflect.Method

1、Type[] getGenericParameterTypes()

描述: 返回值是Type[],Type类型可为Class、ParameterizedType(如:成员变量 List)、TypeVariable(如:成员变量 T)、GenericArrayType(如:成员变量 T[])

 

2、Type getGenericReturnType()

描述: 返回值是Type[],Type类型可为Class、ParameterizedType(如:成员变量 List)、TypeVariable(如:成员变量 T)、GenericArrayType(如:成员变量 T[])

 

3、Type[] getGenericExceptionTypes()

描述: 返回值是Type[],Type类型可为Class、TypeVariable(如:成员变量 T ,T extends Throwable)

 

四、ParameterizedType

Java Type技术笔录_第2张图片 常见调用关系

API:

1、Type[] getActualTypeArguments()

描述: 获取泛型参数的实际参数类型,包含已知全部Type类型: Class、ParameterizeType、TypeVariable、WildcardType和GenericArrayType
 

2、Type getRawType()

描述:获取原始ParameterizedType实际的Class类型

 

3、Type getOwnerType()

描述: 获取外部类的类型,如果没有外部类返回Null

 

代码样例:

public class ParameterizedTypeDemo {

	private static Interface mInterface;

	private static  Interface genericMethod(Interface arg) {
		return null;
	}

	public static void main(String[] args) throws Throwable {
		// RealClassImpl实现的接口是否 “ParameterizedType”
		System.out.println("RealClassImpl's genericInterface is ParameterizedType: "
				+ ParameterizedType.class.isInstance(RealClassImpl.class.getGenericInterfaces()[0]));
		
		// RealClassImpl的父类是否 “ParameterizedType”
		System.out.println("RealClassImpl's genericSuperclass is ParameterizedType: "
				+ ParameterizedType.class.isInstance(RealClassImpl.class.getGenericSuperclass()));

		// mInterface静态成员变量映射的Field字段获取其对应的类型是否 “ParameterizedType”
		Field field = ParameterizedTypeDemo.class.getDeclaredField("mInterface");
		System.out.println(
				"mInterface is ParameterizedType: " + ParameterizedType.class.isInstance(field.getGenericType()));
		
		// genericMethod静态成员方法对应的 “参数” 和 “返回值” 类型是否 “ParameterizedType”
		Method method = ParameterizedTypeDemo.class.getDeclaredMethod("genericMethod", Interface.class);
		System.out.println("genericMethod has ParameterizedType parameters: "
				+ ParameterizedType.class.isInstance(method.getGenericParameterTypes()[0]));
		System.out.println("genericMethod has ParameterizedType return: "
				+ ParameterizedType.class.isInstance(method.getGenericReturnType()));

		// RealClassImpl的父类在继承时声明 “参数化类型” 时,对应其内部的泛型参数是否也是 “ParameterizedType” 
		Type type = ((ParameterizedType) RealClassImpl.class.getGenericSuperclass()).getActualTypeArguments()[0];
		System.out.println("RealClassImpl's genericSuperclass parameter is ParameterizedType:"
				+ ParameterizedType.class.isInstance(type));

		// RealClassImpl实现的接口在指定其参数为 “泛型数组类型” 时,对应泛型数组的内部元素组件类型是否  “ParameterizedType”
		type = ((ParameterizedType) RealClassImpl.class.getGenericInterfaces()[0]).getActualTypeArguments()[0];
		System.out.println("RealClassImpl's genericInterface parameter is GenericArrayType:"
				+ GenericArrayType.class.isInstance(type));
		System.out.println(
				"RealClassImpl's genericInterface parameter is GenericArrayType, and genericComponentType inside GenericArrayType is ParameterizedType:"
						+ ParameterizedType.class.isInstance(((GenericArrayType) type).getGenericComponentType()));
	}

	interface Interface {
	}

	static abstract class AbstractClass {
	}

	static class RealClassImpl extends AbstractClass> implements Interface[]> {
	}
}

 

输出结果: 

RealClassImpl's genericInterface is ParameterizedType: true

RealClassImpl's genericSuperclass is ParameterizedType: true

mInterface is ParameterizedType: true

genericMethod has ParameterizedType parameters: true

genericMethod has ParameterizedType return: true

RealClassImpl's genericSuperclass parameter is ParameterizedType:true

RealClassImpl's genericInterface parameter is GenericArrayType:true

RealClassImpl's genericInterface parameter is GenericArrayType, and genericComponentType inside GenericArrayType is ParameterizedType:true

 

五、TypeVariable

Java Type技术笔录_第3张图片 常见调用关系

 

API:

1、Type[] getBounds()

描述: 获取TypeVariable的边界,如定义Class A,则返回其每个类型对应的Type数组

 

2、D getGenericDeclaration()

描述: 获取声明泛型类型变量的Class、Method或Constructor,泛型简单声明简介如下:

Class声明泛型:

class Sample{}

Method声明泛型:

 void sample(T t){}

Constructor声明泛型

 sample(T t){}

 

代码样例:

public class TypeVariableDemo {

	public static void main(String[] args) throws Throwable {
		// Interface的typeParameters得到其泛型参数是否是 “TypeVariable”
		System.out.println("Interface's typeParameters is only TypeVariable:"
				+ TypeVariable.class.isInstance(Interface.class.getTypeParameters()[0]));

		// RealClass的typeParameters得到其泛型参数是否是 “TypeVariable”
		System.out.println("RealClass's typeParameters is only TypeVariable:"
				+ TypeVariable.class.isInstance(RealClass.class.getTypeParameters()[0]));

		// RealClass's genericMethod 对应的Method获取到的泛型参数是否是 “TypeVariable”
		Method method = RealClass.class.getDeclaredMethod("genericMethod", Exception.class);
		System.out.println("RealClass's genericParameters of genericMethod is only TypeVariable:"
				+ TypeVariable.class.isInstance(method.getGenericParameterTypes()[0]));

		// RealClass's genericMethod 对应的Method获取到的返回值泛型是否是 “TypeVariable”
		System.out.println("RealClass's returnType of genericMethod is only TypeVariable:"
				+ TypeVariable.class.isInstance(method.getGenericReturnType()));

		// RealClass's genericMethod 对应的Method获取到的throws异常类型是否是 “TypeVariable”
		System.out.println("RealClass's throw Excetpion of genericMethod is only TypeVariable:"
				+ TypeVariable.class.isInstance(method.getGenericExceptionTypes()[0]));

		// RealClass's mMemberField 对应的Field获取到的泛型类型是否是 “TypeVariable”
		Field field = RealClass.class.getDeclaredField("mMemberField");
		System.out.println("RealClass's type of mMemberField is only TypeVariable:"
				+ TypeVariable.class.isInstance(field.getGenericType()));

		// InterfaceImpl所实现的接口提供的泛型类型ParameterizedType的actualTypeArguments是否是 “TypeVariable” 
		Type type = InterfaceImpl.class.getGenericInterfaces()[0];
		if (ParameterizedType.class.isInstance(type)) {
			System.out.println("InterfaceImpl's implemented Inteface's GenericType is TypeVariable:"
					+ TypeVariable.class.isInstance(((ParameterizedType) type).getActualTypeArguments()[0]));
		}

		// 在RealClass中的getBounds使用案例
		System.out.println("RealClass's second genericType B getBounds:"
				+ Arrays.toString(RealClass.class.getTypeParameters()[1].getBounds()));

		// 在RealClass中的getGenericDeclaration使用案例
		System.out.println("RealClass's second genericType B getGenericDeclaration:"
				+ RealClass.class.getTypeParameters()[1].getGenericDeclaration());
		System.out.println("RealClass's second genericType S from genericMethod's getGenericDeclaration:"
				+  ((TypeVariable) method.getGenericReturnType()).getGenericDeclaration());
	}

	interface Interface {
	}

	static class InterfaceImpl implements Interface {
	}

	static class RealClass> {
		T mMemberField;

		 S genericMethod(T t) throws T {
			throw (T) new Exception();
		}
	}
}

 

输出结果: 

Interface's typeParameters is only TypeVariable:true

RealClass's typeParameters is only TypeVariable:true

RealClass's genericParameters of genericMethod is only TypeVariable:true

RealClass's returnType of genericMethod is only TypeVariable:true

RealClass's throw Excetpion of genericMethod is only TypeVariable:true

RealClass's type of mMemberField is only TypeVariable:true

InterfaceImpl's implemented Inteface's GenericType is TypeVariable:true

RealClass's second genericType B getBounds:[interface java.lang.Runnable, interface java.io.Serializable, java.util.Comparator]

RealClass's second genericType B getGenericDeclaration:class TypeVariableDemo$RealClass

RealClass's second genericType S from genericMethod's getGenericDeclaration:java.lang.Object TypeVariableDemo$RealClass.genericMethod(java.lang.Exception) throws java.lang.Exception

 

六、WildcardType

Java Type技术笔录_第4张图片 常见调用关系

 

API:

1、Type[] getLowerBounds()

描述: 获取通配符类型的下限边界,如果没有使用? super,返回空数组

 

2、Type[] getUpperBounds()

描述: 获取通配符类型的上限边界,如果没有使用? extends,返回包含一个Object.class元素的数组

 

代码样例:

public class WildcardTypeDemo {

	public static void main(String[] args) throws Throwable {
		// 所实现的接口的内部Interface泛型指定的内部泛型类型是否是 “WildcardType”
		System.out.println(
				"InterfaceImpl's implemented Interface's GenericType of Inner GenericType Interface is WildcardType:"
						+ WildcardType.class.isInstance(
								((ParameterizedType) ((ParameterizedType) InterfaceImpl.class.getGenericInterfaces()[0])
										.getActualTypeArguments()[0]).getActualTypeArguments()[0]));

		// InterfaceImpl的成员方法的Method获取到的泛型参数中泛型的内部参数类型是否是 “WildcardType”
		Method method = InterfaceImpl.class.getDeclaredMethod("genericMethod", Interface.class);
		System.out.println("InterfaceImpl's GenericParamerters's Inner Type of genericMethod is WildcardType:"
				+ WildcardType.class.isInstance(
						((ParameterizedType) method.getGenericParameterTypes()[0]).getActualTypeArguments()[0]));
		// InterfaceImpl的成员方法的Method获取到的返回值类型中泛型的内部参数类型是否是 “WildcardType”
		System.out.println(
				"InterfaceImpl's GenericReturn's Inner Type of genericMethod is WildcardType:" + WildcardType.class
						.isInstance(((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0]));

		// InterfaceImpl的成员变量的泛型的内部参数类型是否是 “WildcardType”
		Field field = InterfaceImpl.class.getDeclaredField("mMememberField");
		Type type = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
		System.out.println("InterfaceImpl's mMememberField's Inner Type of GenericType is WildcardType:"
				+ WildcardType.class.isInstance(type));
		// getLowerBounds和getUpperBounds使用案例
		// mMememberField
		System.out.println("mMememberField getLowerBounds:" + Arrays.toString(((WildcardType) type).getLowerBounds()));
		System.out.println("mMememberField getUpperBounds:" + Arrays.toString(((WildcardType) type).getUpperBounds()));

		// mMememberField1
		field = InterfaceImpl.class.getDeclaredField("mMememberField1");
		type = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
		System.out.println("mMememberField1 getLowerBounds:" + Arrays.toString(((WildcardType) type).getLowerBounds()));
		System.out.println("mMememberField1 getUpperBounds:" + Arrays.toString(((WildcardType) type).getUpperBounds()));
	}

	interface Interface {
	}

	static class InterfaceImpl implements Interface> {

		Interface> mMememberField;
		Interface> mMememberField1;

		Interface genericMethod(Interface f) {
			return null;
		}
	}
}

 

输出结果: 

InterfaceImpl's implemented Interface's GenericType of Inner GenericType Interface is WildcardType:true

InterfaceImpl's GenericParamerters's Inner Type of genericMethod is WildcardType:true

InterfaceImpl's GenericReturn's Inner Type of genericMethod is WildcardType:true

InterfaceImpl's mMememberField's Inner Type of GenericType is WildcardType:true

mMememberField getLowerBounds:[java.util.ArrayList]

mMememberField getUpperBounds:[class java.lang.Object]

mMememberField1 getLowerBounds:[]

mMememberField1 getUpperBounds:[java.util.List]

 

七、GenericArrayType

Java Type技术笔录_第5张图片 常见调用关系

 

API:

1、Type getGenericComponentType()

描述: 获取泛型类型数组,Type为TypeVariable和ParamerizeType类型

 

代码样例:

public class GenericArrayTypeDemo {

	public static void main(String[] args) throws Throwable {
		// 从RealClass实现的接口Interface中提取出泛型类型是否是 “GenericArrayType”
		System.out
				.println("RealClass's implemented Interface's Inner GenericType of its GenericType is GenericArrayType:"
						+ GenericArrayType.class
								.isInstance(((ParameterizedType) RealClass.class.getGenericInterfaces()[0])
										.getActualTypeArguments()[0]));

		// 从RealClass中的genericMethod的Method获取到的泛型参数是否是 “GenericArrayType”
		Method method = RealClass.class.getDeclaredMethod("genericMethod", Object[].class);
		System.out.println("genericMethod's Generic parameterType of its Method is GenericArrayType:"
				+ GenericArrayType.class.isInstance(method.getGenericParameterTypes()[0]));
		// 从RealClass中的genericMethod的Method获取到的返回值类型是否是 “GenericArrayType”
		System.out.println("genericMethod's Generic returnType of its Method is GenericArrayType:"
				+ GenericArrayType.class.isInstance(method.getGenericReturnType()));

		// 从RealClass中的mMemberArray的Field获取其泛型类型是否是 “GenericArrayType”
		Field field = RealClass.class.getDeclaredField("mMemberArray");
		System.out.println("mMemberArray's genericType is GenericArrayType:"
				+ GenericArrayType.class.isInstance(field.getGenericType()));

		// getGenericComponentType使用案例
		System.out.println("mMemberArray's genericComponentType is:"
				+ ((GenericArrayType) field.getGenericType()).getGenericComponentType());
	}

	interface Interface {
	}

	static class RealClass implements Interface {

		T[] mMemberArray;

		 S[] genericMethod(S[] array) {
			return null;
		}
	}
}

 

输出结果: 

RealClass's implemented Interface's Inner GenericType of its GenericType is GenericArrayType:true

genericMethod's Generic parameterType of its Method is GenericArrayType:true

genericMethod's Generic returnType of its Method is GenericArrayType:true

mMemberArray's genericType is GenericArrayType:true

mMemberArray's genericComponentType is:T

 

总结

1、Type定义了Java语言类型最原始的接口;

2、Class是类的原生类型,ParameterizeType、TypeVarible、WildcardType和GenericArrayType是泛型类型;

3、ParameterizeType可以包裹ParameterizeType,从而可以完成深层多层泛型嵌套。

4、结合GenericArrayType和ParameterizeType可以完成一些复杂的泛型类型解析,结合一些开源项目Jackson等完多层级泛型对象的转化...

你可能感兴趣的:(JAVA,Android)