理解:
在运行期,获取类的信息,包括构造方法,字段,名字等类信息。
共同点: get.xxxs
获取公开的xxx数组
getDeclaredxxxs
获取所有的xxx数组(包括私有的)
获取单个同理。
构造方法 Constructor
获取途径
设获取了Class对象Class c = String.class
获取所有公开的构造方法class.getConstructors()
返回一个Constructor
数组。
获取单个公开的构造函数,声明函数的参数就行了(如果B继承A,C继承B,有fun(A),fun(B),我们给了个C参数,会调用fun(B)) getConstructor(Class<?>... parameterTypes)
如果constructor参数是个泛型参数,如果这个类对象其他constructor参数数量相同,会优先调用其它的constructor。
获取所有的构造方法(包括私有的)getDeclaredConstructors()
获取单个构造方法(包括私有的)getDeclaredConstructor(Class<?>... parameterTypes)
通过构造方法获取类
调用Constructor对象的newInstance(Object... initargs)
实例
`String s = String.class.Constructor(Integer.class).newInstance(123);
字段 Field
类似的获取方式。
特殊的操作:
可以获取或设置对象上字段的值,如果要访问为public的字段,要先设置访问权限。
setAccessible(boolean flag)
,只是在此可访问,并不会实际改变字段的权限(private还是pivate)
获取
get(Object obj)
返回指定对象上此 Field 表示的字段的值。
设置
set(Object obj, Object value)
将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
方法 Method
如果要执行非共有的方法,也是要先setAccessible(true);
特殊操作:
方法当然时用来执行的。
Object invoke(Object obj, Object... args)
obj是需要执行这个方法的对象,如果是静态方法,obj可设置为null
,返回的是函数执行的返回值。
返回类型获取
返回类型的类信息
Class returnTypeClass = fun.getReturnType()
注解 Annotation
只有设置了运行时处理的注解才可一被获取到
方法,类,字段都可以获取注解
getDeclaredAnnotation()
也获取不到非运行注解。
获取所有 getAnnotations();
获取单个getAnnotation(Class Annotation)
查看注解某个函数值 假设注解有以下函数String value()
,String name()
获取name的值:annotion.name()
典型代码
//XXX为可以获取注解的类
XXX xx=...;
Annotation[] as = xx.getAnnotations();
for(Annotation a : as)
{
// 如果注解时annotationA类型的
if(a instanceof annotationA)
(annotationA)a.AAA(); //类型转换成A类型的,调用AAA的方法。
}
数组
创建新数组 int[] intArray = (int[]) Array.newInstance(int.class, 0x10);
设置数组某一项的值 Array.set(intArray, 0, 1);
获取某一项的值 int i = (int)Array.get(intArray, 0))
获取数组类信息Class c = int[].class;
其中Class中有判断是否是数组的方法c.isArray()
获取数组组件的class类型c.getComponentType()
示范代码
// Create
int[] intArray = (int[]) Array.newInstance(int.class, 0x10);
// Set
Array.set(intArray, 0, 1);
Array.set(intArray, 1, 2);
Array.set(intArray, 2, 3);
// Get & Print
System.out.println("intArray[0] = " + Array.get(intArray, 0));
System.out.println("intArray[1] = " + Array.get(intArray, 1));
System.out.println("intArray[2] = " + Array.get(intArray, 2));
// 获取数组的类属性 判断是不是数组
Class c = int[].class;
System.out.println(c.isArray());
System.out.println(c.getSimpleName());
if (c.isArray()) {
Class ComponetType = c.getComponentType();
System.out.println(ComponetType.getName());
}
泛型类型信息
泛型ParameterizedType是Type的子接口,通过Type[] getActualTypeArguments()
获取规范化的参数(比如List<String>规范化参数是String,List<List<String>>,规范化参数是List,可以递归操作)。
可以从任何定义泛型的地方获取它的信息。
例子:方法的返回值是List<String>
如果返回类型是个泛型(比如List<String>)可以进一步操作
泛型的意义就是把类型也给参数化,提供检查机制。
//获取泛型
Type returnType = getGenericReturnType();
if(returnType instanceof ParameterizedType){
//返回实际参数数组
Type[] getActualTypeArguments= (ParameterizedType)returnType.getActualTypeArguments()
//这里我们参数List<String>只有一层,所以可以不用递归操作
for(Type t: Type)
{
Class typeArgClass = (Class) t;
System.out.println("typeArgClass = " + typeArgClass);
}
}