• 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();
          }
      }
      

        

  • 相关阅读:
    栈与递归
    细说二叉树的删除操作
    二叉树
    链表队列
    数组队列
    链表栈
    c语言实现数组栈
    c语言实现双链表
    HDU 4557 非诚勿扰(Treap找后继)
    POJ 3481 Double Queue(Treap模板题)
  • 原文地址:https://www.cnblogs.com/lj1507899927/p/13283408.html
Copyright © 2020-2023  润新知