反射 详解

反射

概念:将类的各个组成部分封装为其他对象。

好处:1、可以在程序的运行过程中操作对象。

           2、降低程序的耦合性,提高程序的可扩展性。

看下面的图:反射将在写好的代码中,成员变量,构造方法,成员方法各自拿出进行封装,封装为不同的类。后续就对这些封装好的类进行操作。

 

 

反射获取字节码Class对象的三种方式:对应三种不同阶段

        1、forName获取:       //类还未调用时获取

                    Class<?> class1 = Class.forName("路径比如xxx.xx.x");

        2、通过类名点class获取class对象    //还未创建对象时获取

                    这种是最简单的获取方法,例如:

                                Class<?> class1 = 类名.class;

        3、getClass获取           //创建对象后获取

                    注意:getClass获取前需要先有对象,再通过类名点class获取。

                    比如:Person person = new Person();

                    Class<?> class1 = person.getClass();

Class对象功能:

1、获取成员变量:Field[ ] getFields();          获取某个类的public修饰的成员变量,包括父类的成员变量

                               Field getField(String name);       获取某一个public修饰的成员变量。

 

                               Field[ ] getDeclaredFields();     获取某个类的所有的成员变量(包括private,父类中的不算入内)

                               Field getDeclaredField(String name);   获取某个类的指定成员变量。

                               这里private也能获取到,在反射面前没有什么私有的公有的,你的都是我的,我的还是我的。

                               在使用Declared的时候要忽略访问权限修饰符的安全检查  对象点setAccessible(true);不然会报错。不管是Field还是Method还是Constructor都有这个说法。

                     

2、获取构造方法:

                               Constructor<?>[ ]  getConstructors();

                               Constructor<T>  getConstructor(类<?>...parameterTypes);

 

                                Constructor<?>[ ]  getDeclaredConstructors();

                                Constructor<T>  getDeclaredConstructor(类<?>...parameterTypes);

3、获取成员方法

                                Method[ ] getMethods();

                                Method  getMethod(String name,类<?>...parameterTypes);           //parameterTypes是参数类型

 

                                Method[ ] getDeclaredMethods();

                                Method  getDeclaredMethod(String name,类<?>...parameterTypes);

4、获取类名

                               String getName();

 

目的:

拿到Field是想要干什么?无外乎取值和赋值

    ① 赋值:set方法void set(Object obj,Object value);

                           obj是给哪个对象赋值就是谁,value是赋值为什么内容。

    ② 取值:get方法,get(Object obj);

                           传递的参数obj为被调用的对象

 

构造方法是用来干什么的?为什么要获取构造方法?

        ① 构造方法是用来创建对象的。获取到了构造方法就可以创建对象了。

        ② 获取构造方法:用之前获得的class对象来调用构造方法,返回的类型为Constructor。

                举例:Constructor  cons1 = new Constructor(String.class , int.class);

        ③ 创建对象通过constructor构造出来的对象点newInstance()来实现,返回的对象类型是Object,newInstance中传的是构造这个              实例时所需要传递的真正的值。

                举例:Object object1 = cons1.newInstance("csdn" , 999);

拿到方法后要调用方法,调用方法就要用到invoke();

        //先获取一个Method对象,假设想要获取的是Person类的方法。

           Method add1 = class1.getMethod("addName",String.class);   //这儿第二个参数是方法所需传值的类型,用意在于重载的时               候可以清楚找的是哪个方法。

           Person person = new Person();      //invoke方法中需要传对哪个对象调用的方法,所以这里新建一个对象。

           add1.invoke(person,"张三");           //invoke传的参数,第一个是哪个对象来调用方法,第二个是调用方法时需要传的参数。

 

那我们要反射究竟是要干什么?

        比如:写一个程序,这个程序可以在不改变类的代码前提下,帮我们创建任意类的对象,执行其中的方法。

                  //需要用到反射,配置文件(Properties类,以键值对形式进行参数配置)。

                  //可以将这任意的类放置到配置文件中,再通过反射加载文件,创建对象,执行方法。

 

补充:

        ① 构造方法为空参时创建对象可以简化:

                直接使用Class对象的newInstance方法来创建。

                举例:Object  object1 =  class1.newInstance();

        ② 同一个字节码文件(.class)在一次程序运行过程中,只会被加载一次,不管是通过哪一种方式获取的Class对象,都是同一个。

 

        ③ 获取Class对象的三种方式:forName:通常用于配置文件中

                                                      类名.class:多用于参数的传递

                                                      对象.getClass() :多用于对象获取字节码的方式

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值