反射


反射

0.5

Class类与字节码文件:
Class类是Java反射机制的一部分,它代表了在运行时加载的类和接口。
通过Class类,我们可以获取一个对象所属的类的信息,并进行相应操作。

字节码文件 (.class文件) 是由Java源代码编译而成的二进制文件形成,其中包含了虚拟机能够理解和执行的指令集。
在Java程序运行之前,先将源代码编译为字节码并保存在磁盘上。
当程序需要执行时,虚拟机会读取并解释这些字节码指令来实现对应功能。

1. 类加载器

1, 类加载:

  • 类的加载,类的连接,类的初始化 统称为 类加载。
  1. 类的加载
    • 就是指将 class 读入内存,并为之创建一个java.lang.Class对象
    • 任何类被使用时,系统都会为之建立一个java.lang.Class对象
  2. 类的连接
    • 验证阶段:检验被加载的类是否有正确的内部结构,并和其他类协调一致
    • 准备阶段:负责为类的类变量分布内存,并设置默认初始化值
    • 解析阶段:将类的二进制数据中的符号引用替换为直接引用
  3. 类的初始化
    • 主要是对类变量进行初始化
      1. 先加载并连接该类
      2. 先初始化直接父类
      3. 一次执行初始化语句

2.类加载器

  1. 类加载器作用:负责将类 .class文件加载到内存中,并为之生成对应的 java.lang.Class对象

  2. java 运行时具有以下内置加载器

    1. Bootstrap class loader:  虚拟机的内置加载器,通常表示为null, 没有父null
    2. Platform class loader:  平台加载器......
    3. System class loader:  应用程序加载器......
  3. 类加载器继承关系:

    • System父加载器为Platform,Plagform父加载器为Bootstrap
  4. ClassLoader:

    • 负责加载器的对象
  5. ClassLoader中的两个方法

    1. static ClassLoader getSystemClassLoader():  返回用于委托的系统类加载器
    2. ClassLoader getParent():  返回父类加载器进行委派

2. 反射

  • 技巧:public void setAccessible (boolean flag) : 值为 true ,取消访问检查

1. 获取 class 类对象

  • 要通过反射去实现一个类,首先我们要获取到该类的字节码文件,也就是类型为 Class 类型的对象
  • 获取Class类对象实际上就是在获取对应的字节码文件
  1. 使用类的 class 属性。
    • 例:student.class
  2. 调用对象的 getClass () 方法 (该方法是 Object 类中的方法,所有的 java 对象都可以调用此方法)
    • 例:Student s = new Student (); s.getClass();
  3. 使用 Class 类中的静态方法 forName (String className) ,该方法需要传入字符串参数,也就是某个类的全路径,也就是完整包名的路径
    • 例:Class.forName (“han_2.Student”)

2.反射获取构造方法并使用

  1. Class 类中用于获取构造方法的方法

    1. Constructor<?>[] getConstructors(): 返回所有公共构造方法的数组
    2. Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法的数组
    3. Constructor<?>[] getConstructor(Class<?>...parameter Types): 返回单个公共构造方法
    4. Constructor<?>[] getDeclaredConstructor(Class<?>...parameter Types): 返回单个构造方法对象
  2. Class 类中用于创建对象的方法

    • T newInstance(Object … initargs): 根据指定的构造方法创建对象
  3. 基本数据也可通过 .class来得到对应的 Class 类型

3. 反射获取成员变量并使用

  1. Class 类中用于获取成员变量的方法

    1. Field[] getFields(): 公共数组
    2. Field[] getDeclaredFields(): 所有 数组
    3. Field getField(): 公共单个
    4. Field getDeclaredFields(): 所有 单个
  2. Field 类中给成员对象变量赋值的方法:

    • void set (Object obj, Object value):obj 赋值value

4. 反射获取成员方法并使用

  1. Class 类中用于获取成员方法的方法

    1. Method[] getMethods(): 公共数组(包括继承)
    2. Method[] getDeclaredMethods(): 所有数组
    3. Method getMethod(): 公共单个
    4. Method getDeclaredMethod(): 所有单个
  2. Method 类中用于调用成员方法的方法:

    • Object invoke (Object obj, Object … args): 调用 obj 对象的成员方法,参数是 args ,返回值类型是 Object
  • 总结三步
    1. 得到字节码文件
    2. 得到构造方法
    3. 利用构造方法创建对象
    4. ……

文章作者: han yue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 han yue !
评论
  目录