暴力反射---如何给私有的字段赋值以及调用私有的方法
一、简单了解下什么是反射
1.1、反射:在程序运行过程中(动态),可以对任意一个类型进行任意的操作。例如:加载任意类型、调用类型的任意方法、获取任意的成员变量、构造方法,可以创建该类型的对象
1.2、对于任意一个对象,都能调用这个对象的任意一个方法
1.3、如果要获取一个类型的各种内容,首先要获取这个类的字节码对象(字节码对象属于 Class类型)
1.4、解剖这个类型,获取类中的成员,需要使用Class类型中定义的方法
1.5、这种动态获取信息以及动态访问成员的方式,称为:反射
很多学习java的人或许有点疑惑 “反射到底有什么用?” 因为没有反射的话,对一个类的任意操作都需要重新关闭启动程序,简单点就是没有反射的程序都是“静态”的,有了反射,程序就转变成了“动态”其实就是上面说的在程序运行过程中能够对任意类进行操作
简单反射例子:
public static void main(String[] args) throws Exception {
//获取字节码对象(Class对象)
Class<Cat> catClass = Cat.class;
//调用newInstance()方法获取对象
Cat cat = catClass.newInstance();
}
二、暴力反射
- 常用方法:
- newInstance():创建这个字节码描述的类型的实例对象
- getDeclaredXxx方法:可以获取类中的所有声明的成员(属性、方法、内部类),私有的成员也可以获取到
- setAccessible(boolean flag):设定当前对象是否可以访问
建一个person类
public class Person {
private String name;
private int age;
private void show(String name ,int age){
System.out.println("我叫"+name+"\t"+"今年"+age+"岁了");
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
暴力反射代码案例:
public class PersonReflection {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//获取字节码对象(Class对象)
Class<Person> personClass = Person.class;
//获取私有字段(属性)
Field name = personClass.getDeclaredField("name");
Field age = personClass.getDeclaredField("age");
//设置允许访问
name.setAccessible(true);
age.setAccessible(true);
//先通过反射获取对象,为下面字段赋值和方法执行服务
Person person = personClass.newInstance();
//给字段(属性)设置值
name.set(person,"lichaohua");
age.set(person,21);
//获取私有方法
Method show = personClass.getDeclaredMethod("show", String.class, int.class);
//设置允许访问
show.setAccessible(true);
//调用方法
show.invoke(person,person.getName(),person.getAge());
} }
输出结果: