首先创建一个类
public class ReflectDemo {
private int m=0; //私有属性
private ReflectDemo(){ //私有无参构造函数
}
public ReflectDemo(int aa){
//有参构造函数
}
private int add(int a,int b){ //私有方法
return a+b;
}
public int getM(){
return m;
}
}
在这里要先说一下构造函数:
构造函数分为公有的和私有的,定义成private,在类的外面,就不能生成类的对象了
如果一个类没有提供任何的构造函数,会自动生成一个无参的构造函数,这个构造函数是public。
然后我们要了解三个反射包中的类:
Constructor:代表类的单个构造方法,通过Constructor我们可以执行一个类的某个构造方法(有参或无参)来创建对象。
Method:代表类中的单个方法,可以用于执行类的某个普通方法,有参或无参,并可以接收返回值。
Field:代表类的单个属性,用于set或get该属性。
setAccessible: setAccessible()方法来抑制Java访问权限的检查的。
AccessibleObject:以上三个类的父类,提供了对构造方法、普通方法、和属性的访问控制的能力。
public class ReflectTest {
public static void main(String[] args) throws Exception {
/**
* 创建私有化类的对象
*/
//1.获取类的无参构造方法
Constructor<ReflectDemo> constructor=ReflectDemo.class.getDeclaredConstructor();
//2.设置取消访问检查,是访问私有构造方法的关键
constructor.setAccessible(true);
//3.调用该构造方法,获得对象
ReflectDemo reflectDemo=constructor.newInstance();
/**
* 使用反射调用私有方法
*/
//1.根据方法名和方法参数获取方法对象
//第一个参数是具体调用该方法的对象
//后面参数是执行该方法的具体参数
Method method=ReflectDemo.class.getDeclaredMethod("add",int.class,int.class);
//Method method=ReflectDemo.class.getDeclaredMethod("add",new Class[]{int.class,int.class}); 另一种方法
//2.取消访问检查,是访问私有方法的关键
method.setAccessible(true);
//3.调用私有方法并获得返回值
int i=(Integer) method.invoke(reflectDemo, 1,2);
System.out.println(i);
/**
* 使用反射改变私有属性
*/
Field field=ReflectDemo.class.getDeclaredField("m");
field.setAccessible(true);
field.setInt(reflectDemo, 2);
System.out.println(reflectDemo.getM());
/**
* 通过new对象,这里因为ReflectDemo设置了私有的无参构造函数所以不能实例化无参的对象。
*/
ReflectDemo ddd=new ReflectDemo(22);
//这里的对象ddd与上面的reflectDemo是不同的对象,所以上面通过反射设置的私有属性并不会影响这里的对象
System.out.println(ddd.getM());
}
}
method中的invoke方法:
函数原型:Object Java.lang.reflect.Method.invoke(Object receiver, Object… args)
//Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,
//如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,
//如果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回
receiver:该方法所在类的一个对象
args: 传入的参数 如 100,“hello”
输出结果: