Java中反射机制的理解

  1. java反射的概念
    • 在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。简单的说,反射机制就是在程序的运行过程中被允许对程序本身进行操作,比如自我检查,进行装载,还可以获取类本身,类的所有成员变量和方法,类的对象,还可以在运行过程中动态的创建类的实例,通过实例来调用类的方法,这就是反射机制一个比较重要的功能了。
  2. 理解反射机制,首先要理解类的加载过程
    • 加载过程图                                                                                                     
    • 在Java程序执行的时候,要经历三个步骤:加载、连接和初始化。首先程序要加载到JVM的方法区中,然后进行连接,最后初始化。这里就主要介绍一下类的加载。如上图,首先,JVM会从硬盘中读取Java源文件并将其加载到方法区中同时生成类名.class文件,也就是类对象,这个类对象中包含了我们创建类的实例时所需要的模板信息,也就是源代码中的成员变量和方法等。Class本身也是一个类,它的主要功能之一就是生成类加载时的class文件,为类的初始化及实例化做准备。而我们在程序中通过关键字new创建的对象创建的是类的对象,而不是类对象,二者的区别如图中所示。

  3. 原理模型                                                                      
  4. 常用的反射类以及用法
    •  java.lang.class
      • (调用某个对象的getClass()方法
        User user=new User()
        Class clazz=user.getClass()

      • 调用某个类的class属性来获取该类对应的Class对象
        Class clazz=User.class

      • 调用包的地址
        Calss clazz=Class.forName("")

    • java.lang.reflect.Method
      • 获取类的所有方法信息getDeclaredMethods()

      • 获取类的公有方法信息getMethods()

      • 要注意的是,在暴力获取私有方法后还要获取调用该方法的权限:.setAccessible(true)(默认false,需要设置成true)

    • java.lang.reflect.fields
      • 获取类的所有成员属性信息getDeclaredFields()

      • 获取类的公有成员属性信息getFields()

    •  java.lang.reflect.constructor
      • 获取类的所有构造方法信息getDeclaredConstructors()

      • 获取类的公有构造方法信息getConstructors()

  5. 创建实例的两种方式
    • 使用Class对象的newInstance()方法来创建该Class对象对应类的实例,但是这种方法要求该Class对象对应的类有默认的 空构造器。

    • 先使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建 Class对象对应类的实 例,通过这种方法可以选定构造方法创建实例。

  6. Java反射优缺点
    • Java反射优点:在运行期确定对象、绑定对象、操作对象,最大限度的发挥了Java的灵活性。

    • Java反射缺点:反射相当于一系列解释操作,通知jvm要做的事情,性能相对较低。反射会跳过类型检查等,导致安全性问题。例如通过反射跳过泛型的编译前类型检查

  7. 应用场景
    • 框架中的xml,properties等配置

    • 框架中注解的使用

    • 动态代理、AOP

    • JDBC数据库连接

  8. 例子
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    import com.javasm.lang.Person;
    
    public class PersonTest3 {
    
        /**
         * 操作类的属性/成员变量
         * 操作方法---->操作Method类
         * 操作构造---->操作Constructor类
         */
        public static void test1() {
            try {
                Person person = new Person();
                //1.创建Class类的实例
                Class clazz = Class.forName("com.lj.bean.Person");//类或者接口的全限定名称  包名+类名
                Method[] methods = clazz.getMethods();//只获得public方法(包含从父类继承的)
                System.out.println(Arrays.toString(methods));
    
                methods = clazz.getDeclaredMethods();//只获得本类里面public/protected/默认/private
                System.out.println(Arrays.toString(methods));
                // String 方法名     parameterTypes:参数类型  可变参数 >=0实参
                //对name赋值  setName
                Method method = clazz.getMethod("setName", String.class);
    
                //运行方法
                Object obj = method.invoke(person, "张三");//方法的参数数据
    
                System.out.println(obj);
                System.out.println("person:"+person.getName());
    
                System.out.println("------------------------------");
                //执行b方法
                method = clazz.getDeclaredMethod("b", String.class,Integer.class);
                method.setAccessible(true);
    
                obj = method.invoke(person, "hello world",100);
    
                System.out.println(obj);
            } catch (ClassNotFoundException|NoSuchMethodException|SecurityException e) {
                e.printStackTrace();
            } catch (IllegalAccessException |IllegalArgumentException |InvocationTargetException e) {
                e.printStackTrace();
            } 
    
        }
        public static void main(String[] args) {
    
            test1();
        }
    }
    

      

posted @ 2020-07-11 14:11  小呆俊  阅读(215)  评论(0编辑  收藏  举报
/*标题彩虹滚动字*/ #blogTitle h1 a{ background-image: -webkit-gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2), color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) ); color: transparent;-webkit-text-fill-color: transparent; -webkit-background-clip: text; -webkit-background-size: 200% 100%; -webkit-animation: maskedAnimation 2s infinite linear; -webkit-background-clip: text;-moz-background-clip: text;-ms-background-clip: text /*文字颜色变化*/ @keyframes maskedAnimation { 0% { background-position: 0 0; } 100% { background-pos