java反射机制

心已入冬 提交于 2020-01-29 13:28:47

反射在java中占据很重要的地位,spring的IOC/DI背后依靠的就是java的反射机制。不仅spring使用反射机制,Hibernate的ORM框架也是反射机制实现的,AOP动态代理也大量使用了反射技术,在不知不觉中,java的反射机制其实已经被大量应用在我们的程序中。

java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性方法;对于任意一个对象都能调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能成为java的反射机制。

反射的优点就是动态灵活,一切都是在运行时期根据具体情况(配置)决定创建哪种对象、调用哪个方法等。这种灵活性可以方便我们设计解耦,这也是Spring做得最好的事情之一,所以我们可以很方便的替换某些class文件而不需要重新编译相关类。事物都是两面的,反射当然也有缺点,对于编译期能确定的事情,编译器可以或多或少做些优化,而运行期就像解释执行一样,编译器一般没法进行优化,所以使用反射性能要打点折扣;另外反射破坏类的封装性,通过反射我们可以访问类的任何成员,包括private成员,这违反了面向对象设计原则。

java.lang.Class类:反射中最常出现的类,它跟其它JAVA类没什么两样只是名字恰巧叫Class,都是继承于Object类,其实它就是JAVA类的抽象,用来描述类的元数据,比如每个类都有类名、装载器、哈希等,这些都是Class类的属性。Class没有public的构造函数,当Java虚拟机载入一个类的时候,它就会自动创建一个Class类的实例来表示这个类,比如java.lang.String,我们可以通过String.class来获取对应的Class类实例;或者我们也可以通过Class.forName("类全名")来获取一个Class对象。

类加载:

       当JVM第一次使用一个类时,需要通过ClassPath找到这个类对应的.class文件,把这个文件中包含的类的信息读入JV并保存起来一般的说,一个类只会加载一次。

反射常用方法介绍:

 1. Class: 是一个类; 一个描述类的类.

  封装了描述方法的 Method,
        描述字段的 Filed,
                  描述构造器的 Constructor 等属性.

 2. 获取Class对象的三种方式.

     2.1>Class.forName("完整的类名字符串");

     2.2>类名.class

     2.3>指定类对象.getClass();

     最常用的是Class.forName("完整的类名字符串");

 3. 关于 Method:
    3.1 如何获取 Method:
      Method[] getMethods[];获取当前类所有的public修饰的成员方法;这里会显示父类继承而来的方法

                Method[] getDeclaredMethods(); 获取当前类里面的所有方法,包括private修饰的方法,但是会guolv父类继承而来的方法

                Method getMethod(String methodName,Object... args); 根据方法的名字和对应的参数列表,获取指定方法

                Method getDeclaredMethod(String methodName,Object... args); 根据方法的名字和对应的参数列表,获取指定方法;可以获取private修饰的方法

         3.2 如何调用 Method
      1). 如果方法时 private 修饰的, 需要先调用 Method 的 setAccessible(true), 使其变为可访问
      2). method.invoke(obj, Object ... args);第一个参数是执行该方法的类对象,第二个是执行该方法需要的参数列表

  4. 关于 Field:
      4.1 如何获取

           Field[] getFields(); 获取所有的用public修饰的成员变量

           Field[] getDeclaredFields(); 获取所有的成员变量,包括private修饰在类的成员变量

           Field getField(String fieldName); 根据成员变量的名字获取成员变量

           Field getDeclaredField(String fieldName); 根据成员变量的名字获取包括private修饰在内的成员变量

    4.2 如何获取 Field 的值:
      1). setAccessible(true)
      2). field.get(Object obj)
    4.3 如何设置 Field 的值:
      field.set(Obejct obj, Object val)) 设置成员变量的数值,第一个参数是调用该成员变量的对象,第二个参数是赋予数值

  5.Constructor常用方法

     Constructor[] getConstructor();获取所有的public修饰的构造方法

    Cosntructor getDeclaredConstructor();获取当前类里面所有的构方法,包含私有化的构造方法

    Constructor getConstructor(Object... paramterTyeps); 根据所需参数不同,获取指定的构造方法对象

    Constructor getDeclaredConstructor(Object... paramterTyeps); 根据所需参数不同,获取指定的构造方法对象包含私有化的构造方法

    Object newInstance(Object... initargs); 给予确定的参数,通过反射嗲用构造方法,这里的参数列表是一个不定参数列表

  6.暴力反射赋予权限的函数是 setAccessible(boolean boolea)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!