被视为动态语言的关键,反射机制允许程序在执行期期间能够获得任何类的内部信息,并能直接操作任意对象的内部属性及方法
创建一个类,通过编译(javac.exe)生成对应的.class文件。之后我们使用Java.exe加载(JVM的类)此.class文件,此.class文件加载到内存后,就是一个运行时类,存放在缓存区,那么这个运行时类本身就是一个Class的实例!
1.每一个运行时类只加载一次
2.有了class的实例后,才可以进行如下操作
1)创建对应的运行时类的对象
2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在的包、异常、注解……)
3)调用对应的运行时类的指定的结构(属性、方法、构造器)
4)动态代理
获取需要反射的字节码对象
1.Object类中getClass方法(需要明确类名Person,并创建对象)
Person p=new Person();
Class clazz=p.getClass();
2.任何数据类型都具备一个静态属性,.class来获取其对应的Class对象(需要明确类名Person)
Class clazz=Person.class;
3.只要通过给定的类的字符串名称就可以获取该类,可以用Class类中的方法完成
String className="cn.itcast.bean.Person";
Class clazz=Class.forName(className);
找该名称类文件,加载进内存,并产生Class对象
Class clazz=Class.forName(name);
获取到了指定的构造函数对象
Constructor constructor =clazz.getConstructor(类名);
/通过改构造器对象的newInstance方法进行对象的初始化
Object obj=constructor.new Instance("小明",38);
1.getFields():只能获取到运行时类中声明为public的属性
Class clazz= testList.Person.class;
Field[] fields=clazz.getFields();
for (int i=0;i
2.getDeclaredFields():获取运行时类声明的所有的属性
Field[] fields1=clazz.getDeclaredFields();
for (Field f:fields1){
System.out.println(f.getName());
}
1.获取运行时类及其所有父类中所有声明为public的方法
getMethods()
2.获取运行时类(没有父类)中声明的所有方法
getDeclareMethods();
3.获取注解
getAnnotations();
4.获取权限修饰符
getModifiers();
5.获取返回值类型
getReturnType();
6.获取方法名
getName();
7.形参列表
getParameterTypes();
public static void test2(){
Class clazz= testList.Person.class;
Method[] m1 =clazz.getDeclaredMethods();
for (Method m:m1){
//注解
Annotation[] ann =m.getAnnotations();
for (Annotation a:ann){
System.out.println(a);
}
//权限修饰符
String str = Modifier.toString(m.getModifiers());
System.out.println(str+" ");
//返回值类型
Class returnType=m.getReturnType();
System.out.println(returnType.getName()+" ");
//方法名
System.out.println(m.getName());
//System.out.println(m);
//形参列表
Class[] params=m.getParameterTypes();
for (int i=0;i
1.运行时父类
2.带泛型的父类
getGenericSuperclass();
Class clazz= testList.Person.class;
Type type1=clazz.getGenericSuperclass();
//System.out.println(type1);
3.获取父类的泛型
ParameterizedType
Class clazz= testList.Person.class;
Type type1=clazz.getGenericSuperclass();
ParameterizedType param=(ParameterizedType)type1;
Type[] ars=param.getActualTypeArguments();
System.out.println(((Class)ars[0]).getName());
4.获取实现的接口
getInterfaces();
5.获取所在的包
getPackage();
1.指定属性
Fieldname=clazz.getField("age");
2.创建运行时类的对象
testList.Personp=(testList.Person)clazz.newInstance();
3.将运行时类的指定的属性赋值
name.set(p,"jerry");
4.获取运行时勒种指定的名为fieldName的属性
getDeclareField(StringfieldName);
5.由于属性权限修饰符的限制,为了保证可以给属性赋值,需要再操作前使此属性可被操作
age.setAccessible(true);
age.set(p,10);
1.获取运行时类中声明为public的方法
getMethod(String methodName,Class … params)
2.调用指定方法
Object invoke(Object obj,Object… obj)
3.调用运行时类中静态方法
getMethod
4.运行时类中声明了的方法
//设置此方法可被操作
m.setAccessible(true);
getDeclareMethod(String methodName,Class … params)