java Type 及其子类介绍
Type
是java反射机制中提供的一个接口,用来表示java
中的所有类型的接口,定义如下:
package java.lang.reflect;
public interface Type {
default String getTypeName() {
return this.toString();
}
}
Type
是java
编程语言中所有类型的通用超级接口,包括原始类型Class
,参数化类型,数组类型,类型变量和基本类型。其子类有:
原始类型Class
Class
类的实例用来表示java
中所有的类, 可以用Class.forName
加载一个类,也可以获取到通过一个类的Class
对象获取到该类的所有属性,方法,继承的类和接口。
Class<?> clz = MethodHandle.class;
Constructor<?>[] cons = clz.getConstructors();
Method[] methods = clz.getMethods();
Field[] fields = clz.getFields();
泛型数组类型 GenericArrayType
接口GenericArrayType
代表泛型数组类型,泛型数组指数组中元素是参数类型或者类型变量。
class GenericArrayTypeTest<T> {
List<Integer>[] field1;
T[] field2;
}
public static void genericArrayTest() {
Class<?> clazz = GenericArrayTypeTest.class;
try {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
Type type = field.getGenericType();
// 输出 java.util.List<java.lang.Integer>[] / T[]
System.out.println(type);
}
} catch (Exception e) {
e.printStackTrace();
}
}
参数化类型ParameterizedType
接口ParameterizedType
表示参数化类型,例如Collection<String>
;他在反射方法第一次使用参数化类型时被创建,当一个ParameterizedType
实例被创建时,将递归解析类型声明中的所有类型参数。
class ParameterizedTypeTest {
public Map<String, Integer> failed1;
public List<String> failed2;
}
public class TypeReview {
public static void main(String[] args) {
Class<?> clz = ParameterizedTypeTest.class;
Field[] fields = clz.getFields();
for (Field field : fields) {
Type ftype = field.getGenericType();
if (ftype instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) ftype;
// 获取参数类型名称,Map<String, Integer>和 List<String>
System.out.println(parameterizedType.getTypeName());
// null
System.out.println(parameterizedType.getOwnerType());
// 获取原始类型,输出为interface java.util.Map/List
System.out.println(parameterizedType.getRawType());
// 获取实际类型参数
for (Type ptype : parameterizedType.getActualTypeArguments()) {
System.out.println(ptype.getTypeName());
}
}
}
}
}
class ParameterizedTypeTest {
public Map<String, Integer> failed1;
public List<String> failed2;
}
类型变量TypeVariable
TypeVariable
代表在Java
类,构造方法和方法中声明的类型变量:
class TypeVariableTest<T> {
public <E> TypeVariableTest() {
}
public <F> void method1() {
}
}
public static void main(String[] args) {
Class<TypeVariableTest> clazz = TypeVariableTest.class;
TypeVariable<?>[] typeVariable = clazz.getTypeParameters();
for (TypeVariable<?> variable : typeVariable) {
System.out.println(variable.getGenericDeclaration());
System.out.println(variable.getName());
System.out.println(variable.getTypeName());
}
try {
Method method = clazz.getMethod("method1");
TypeVariable[] typeVariables = method.getTypeParameters();
for (TypeVariable variable : typeVariables) {
System.out.println(variable.getTypeName());
}
Constructor<?> constructor = clazz.getConstructor();
typeVariables = constructor.getTypeParameters();
for (TypeVariable variable : typeVariables) {
System.out.println(variable.getTypeName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
WildcardType
通配符类型
表示一个通配符表达式,如?
,? extends Collection
,? super List
。该接口提供的方法有:
// 返回上界
Type[] getUpperBounds();
// 返回下界
Type[] getLowerBounds();
Mybatis源码中Type使用示例
示例1:org.apache.ibatis.reflection.Reflector
中的typeClass
方法将Type
类型对象转换为Class
对象:
private Class<?> typeToClass(Type src) {
Class<?> result = null;
// 如果src是Class类型的实例则直接进行强制类型转换
if (src instanceof Class) {
result = (Class<?>) src;
// 如果src是参数类型则获取其原始类型Class对象;
} else if (src instanceof ParameterizedType) {
result = (Class<?>) ((ParameterizedType) src).getRawType();
//
} else if (src instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) src).getGenericComponentType();
if (componentType instanceof Class) {
result = Array.newInstance((Class<?>) componentType, 0).getClass();
} else {
Class<?> componentClass = typeToClass(componentType);
result = Array.newInstance(componentClass, 0).getClass();
}
}
if (result == null) {
result = Object.class;
}
return result;
}
Class对象中getField(s)/getDeclaredField(s)区别:
getField(s):
用来获取Class
对象所表示类中的公开方法,getMethod(String name , Class<?>... parameterTypes)
获取指定名称和参数类型的方法的Method
对象,getMethods
获取所有公开方法;
getDeclaredField(s)
获取Class
对象所表示类中所有声明的方法,参数和返回类型同getMethod(s)
;
getMethod(s)
/getDeclaredMethod(s)
,getConstructor(s)
/getDeclaredConstructor(s)
用法与之相似