一.反射
反射:在jvm运行中获取类的属性、方法等信息,并能动态创建类的实例,调用类的方法
1.获取字节码Class
//方式1:根据类获取Class
Class c1=Person.class;
Person p=new Person("张三",23);
//方式2:根据对象获取Class
Class c2=p.getClass();
//方式3:根据带包名的类路径获取Class
Class c3=Class.forName("com.bean.Person");
2.获取构造方法
-
Class
Constructor<T> getConstructor(Class<?>... parameterTypes)
根据参数列表类型获取public
修饰的构造器
*-Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
暴力获取各种权限修饰符修饰的构造器
-
Constructor
T newInstance(Object... initargs)
传递实参创建实例
//获取Person的字节码
Class<Person> clazz=Person.class;
//获取无参构造
Constructor<Person> c1=clazz.getConstructor();
//根据无参构造创建实例
Person p1= c1.newInstance();
//获取指定参数类型的有参构造
Constructor<Person> c2=clazz.getConstructor(String.class,int.class);
//根据有参构造创建实例
Person p2= c2.newInstance("张三",23);
3.获取字段
-
Class
Field getField(String name)
根据名称获取public
修饰的字段,包括静态字段Field getDeclaredField(String name)
暴力获取各种权限修饰符修饰的字段
-
Field
Object get(Object obj)
获取指定对象的字段值,还有getInt(),getBoolean()等 -
方法
void set(Object obj, Object value)
为指定对象的字段设置值
//类反射根据空参创建实例
Class<Person> clazz=Person.class;
Constructor<Person> c=clazz.getConstructor();
Person p=c.newInstance();
//获取age属性
Field f=clazz.getField("age");
//为p对象的age属性赋值
f.set(p, 23);
System.out.println(p);
//获取p对象的age值
int age=f.getInt(p);
System.out.println(age);
4.获取方法
-
Class
Method getMethod(String name, Class<?>... parameterTypes)
根据方法名和参数列表类型获取public
修饰的方法,包括静态方法Method getDeclaredMethod(String name, Class<?>... parameterTypes)
暴力获取所有权限修饰符的方法
-
Method
Object invoke(Object obj, Object... args)
为指定对象传递实参执行方法
//反射创建实例
Class<Person> clazz=Person.class;
Constructor<Person> c=clazz.getConstructor(String.class);
Person p=c.newInstance("张三");
//根据方法名和参数列表类型获取方法
Method m=clazz.getMethod("setName", String.class);
//为p对象执行有参方法
m.invoke(p, "李四");
//执行无参方法
clazz.getMethod("print").invoke(p);
5.暴力获取
- AccessibleObject(直接已知子类: Constructor, Field, Method )
void setAccessible(boolean flag)
是否取消java语言的权限访问检查
Class<Person> clazz=Person.class;
//暴力获取非公有构造器
Constructor<Person> c=clazz.getDeclaredConstructor(String.class);
//取消构造器的访问权限检查
c.setAccessible(true);
//根据非公有的构造器创建实例
Person p=c.newInstance("张三");
//暴力获取非公有字段
Field f=clazz.getDeclaredField("name");
//取消字段的访问权限检查
f.setAccessible(true);
//获取或设置非公有的字段
f.set(p, "李四");
String name=(String)f.get(p);
System.out.println(name);
//暴力获取非公有的方法
Method m=clazz.getDeclaredMethod("setName", String.class);
//取消方法的访问权限检查
m.setAccessible(true);
//执行非公有的方法
m.invoke(p, "王五");
System.out.println(p);