java内功提升-反射

java内功提升-反射

​ 在程序运行时,通过.class文件获得类中的内容(构造方法,成员方法,属性等),并且进行操作

初始化一个类需要哪些步骤?

​ 1.加载.class文件,创建Class对象;

​ 2.连接:校验Class对象的完整性和正确性

​ 3.初始化

​ 创建一个空白的对象实例(只有引用没有内容)

​ 初始化父类对象(如果继承了父类)

​ 添加成员变量,成员方法(静态变量在类被加载到jvm中的时候就已经创建)

​ 运行实例程序

使用反射的步骤

​ 1.创建Class对象

三种方式:

​ (1).调用Class.forName(“类的完整路径”)

​ (2).调用实例对象的getClass()方法

​ (3).通过.class文件赋值得到:Class clazz = Person.class

​ 2.获取构造方法

​ Constructor constructor = clazz.getConstructor();

​ 3.获得对象实例

​ Object obj = constructor.newInstance();

​ 4.获得字段/获得方法

​ Field field = clazz.getFiled(name);

​ Method method = clazz.getMethod(methodName, paramTypeClass);

​ 5.给字段赋值或得到字段的值/调用方法得到返回值

​ field.set(obj, value);
​ field.get(obj);
​ method.invoke(obj,params); //传入的是对象和参数

获取构造方法
		//获取Test类的Class对象
        Class<Test> clazz = Test.class;
        //通过反射获取构造方法
        Constructor<Test> constructor = clazz.getConstructor();
		//获取Test类的私有构造方法
        Field declaredField = clazz.getDeclaredField();
        //通过反射获取Test类的实例
        Test test = constructor.newInstance();
获取Field
		//获取Test类的Class对象
        Class<Test> clazz = Test.class;
        //获取属性名为name的Filed属性对象,不包括私有属性
        Field age = clazz.getField("age");
        //获取Test的所有属性对象,包括父类中的公有属性,不包括私有属性
        Field[] fields = clazz.getFields();
        //获取Test的名为age的属性对象,包括私有属性
        Field declaredField = clazz.getDeclaredField("age");
		//获取Test中的所有属性,包括父类中的公有属性,包括私有属性
        Field[] declaredFields = clazz.getDeclaredFields();
        //给age属性赋值
        age.set(18);
        //得到age对象的名字
        age.getName();
获取Method
		Constructor<Test> constructor = clazz.getConstructor();
        Test test = constructor.newInstance();
        //获取名为eat()的方法,不包括私有方法
        Method method = clazz.getMethod("eat");
        //获取所有的方法,包括父类中的公有方法,不包括私有方法
        Method[] methods = clazz.getMethods();
        //获取名为eat的方法,包括私有方法
        Method declaredMethod = clazz.getDeclaredMethod("eat");
        //获取所有的方法,包括父类中的方法,包括私有方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        //调用执行该方法,并传入test实例和参数
        method.invoke(test,"肉");
暴力访问
 		//获取Test类的Class对象
        Class<Test> clazz = Test.class;
        Test test = clazz.getConstructor().newInstance();
        //获取名为name的私有字段
        Field name = clazz.getDeclaredField("name");
        //给属性赋值
        name.set(test,"张三");
上面的代码有什么问题吗?

​ 看似没有问题,其实私有字段是不能通过外部来进行赋值的,那么如何解决?

		//获取Test类的Class对象
        Class<Test> clazz = Test.class;
        Test test = clazz.getConstructor().newInstance();
        //获取名为name的私有字段
        Field name = clazz.getDeclaredField("name");
		//设置暴力访问
        name.setAccessible(true);
        //给属性赋值
        name.set(test,"张三");		

​ 看出来了吗?对了,只要加上**setAccessible()**这个方法,并且将它设置为true就可以对私有的属性、方法等 进行操作了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值