通过反射创建私有化类的对象,调用类的私有方法,改变私有属性

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nb7474/article/details/79679629

首先创建一个类

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”

输出结果:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/nb7474/article/details/79679629