Java反射、内省、动态代理

456 阅读3分钟

类加载机制

  • 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载连接初始化来对这个类进行初始化
  • 加载:
    • 就是将.class文件读入内存,并为之创建一个Class对象。
    • 任何类被使用时,系统都会创建一个Class对象。
  • 连接: 连接阶段负责把类的二进制数据合并到JRE中
    • 验证:是否有正确的内部结构,并和其他类协调一致。
    • 准备:负责为类的静态Field分配内存,并设置初始值。
    • 解析:将类的二进制数据中的符号引用替换成直接引用。
  • 初始化:该阶段主要是对静态Field进行初始化。
  • 类的加载时机:
    • 创建类的实例的时候
    • 访问类的静态变量,或者为静态变量赋值
    • 调用类的静态方法
    • 使用反射来创建类的实例
    • 初始化某个类的子类
    • 直接使用java.exe了运行某个类
    • baijiahao.baidu.com/s?id=163630…

类加载器的概述

  1. 概述:类加载器负责将.class文件加载到内存,并为之创Class对象。
  2. 类加载器的组成:
    • Bootstrap ClassLoader 根类加载器
      • 负责java核心类加载,比如SystemString类,在JRE目录下lib的rt.jar
    • Extension ClassLoader 扩展类加载器
      • 负责JRE目录下ext目录下jar的加载
    • System ClassLoader 系统类加载器
      • 负责JVM 启动时来自java命令的类
      • 以及classpath环境变量下所指定的jar包和类路径
      • 所以一般程序员的工程里的类和jar由系统类加载器加载、

反射

  1. 概述:java反射技术是指在程序运行时,可以对任意一个类,都能够获取它的属性和方法、对任意一个对象都能够调用它的方法,这种动态获取类信息和动态调用对象方法称为java的反射机制。
  2. 简单来说就是动态操作Class类:
    • 成员变量:Field
    • 构造方法:Constructor
    • 成员方法:Method

获取Class对象的三种方式

        //第一种方式
        Person person = new Person();
        Class c1 = person.getClass();

        //第二种方式
        Class c2 = Person.class;

        // 第三种方式
        Class c3 = Class.forName("com.alita.Person");

构造方法

        // 返回指定参数的公共构造器
        Constructor constructor1 = c1.getConstructor(String.class, Integer.class);
        // 返回指定参数的公共、私有、保护等构造器
        Constructor constructor2 = c1.getDeclaredConstructor(String.class, Integer.class);
        // 返回所有公共构造器
        Constructor[] constructors1 =c1.getConstructors();
        //所有构造器
        Constructor[] constructors2 =c1.getDeclaredConstructors();
        //创建对象
        Person p = (Person) constructor1.newInstance();

成员变量

        // 公共的成员变量
        Field f1 = c1.getField("age");
        Field[] fields1 = c1.getFields();
        // 包括私有,受保护的成员变量
        Field f2 = c1.getDeclaredField("age");
        Field[] fields2 = c1.getDeclaredFields();
        // 赋值
        f1.setInt(person, 18);
        f1.get(person);

成员方法

        Method m1 = c1.getMethod("show");
        // 获取自己的包括其父类所有公共方法
        c1.getMethods();
        // 只获取自己的所有的公共方法

        Method m2 = c1.getDeclaredMethod("show",String.class);
        m1.invoke(person,"arg");

Java的内省机制

  1. 概述:基于反射基础上实现的Java的内省(Introspector)机制能够专门针对JavaBean对象,提供方便快捷的反射操作。
        // 获取JavaBean描述对象beanInfo
        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
        // 获取所有的 属性
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor pds : propertyDescriptors) {
            pds.getPropertyType();
            pds.getReadMethod();
            pds.getWriteMethod();
            pds.getName();
        }
        // 手动创建 属性描述器,此时必须保证get 和 set方法 同时 存在
        PropertyDescriptor pd =new PropertyDescriptor("age",Person.class);
        Method method = pd.getReadMethod();
        int age = (int)method.invoke(person);