Java反射-个人学习

    技术2026-06-21  3

    文章目录

    反射1.类的加载、连接和初始化1.1 类的加载1.2 类的连接1.3 类的初始化1.4 类加载器1.4.1 类加载器的组成 1.5 JVM的类加载机制 2.反射概述2.1 Java反射机制2.2 获取Class类的对象2.3 反射获取构造方法并使用2.4 反射获取成员变量并使用2.5 Class类中用于获取成员方法的方法

    反射

    1.类的加载、连接和初始化

    程序要用到某个类的时候,如果该类还未被加载到内存中时,系统会通过类的加载、类的连接、类的初始化这三个步骤来对类进行初始化。如果不出意外情况,JVM会连续的完成着三个步骤,所有时候也把这三个步骤统称为类加载或类初始化。

    1.1 类的加载

      将class文件读入内存,并创建一个java.lang.Class对象   任何类被使用时,系统都会建立一个java.lang.Class对象

    1.2 类的连接

      验证阶段:用于检测被加载的类是否有正确的内部结构,并和其他类协调一致。   准备阶段:负责为类的类变量分配内存并设置默认初始化   解析阶段:将类的二进制数据中的符号引用替换为直接引用

    1.3 类的初始化

      主要就是对类变量进行初始化

    类的初始化步骤:

    假如类还未被加载和连接, 则程序先加载并连接该类假如该类的直接父类还未被初始化, 则先初始化其直接父类假如类中有 初始化语句,则系统依次执行这些初始化语句 注意:在执行第2个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3

    类的初始化时机:

    创建类的实例调用类的类方法访问类或者接口的类变量,或者为该类变量赋值使用反射方式来强制创建某 个类或接口对应的java.lang.Class对象初始化某个类的子类直接使用java.exe命令来运行某个主类

    1.4 类加载器

    java9之前: 类加载器的作用

    负责将.class文件加载到内存中, 并为之生成对应的java.lang.Class对象 不用过分关心类加载机制,但是了解这个机制能更好的理解程序的运行

    1.4.1 类加载器的组成

    Java 9之前的类加载器分成三个层次(JDK 1.2之前是两个层次),分别是:

    **引导类加载器(boostrap class loader):**虚拟机内置的类加载器,通常以null表示,从引导类路径加载。**扩展类加载器(extension class loader):**从扩展目录加载类。它是JDK 1.2中引入的扩展机制的产物。它的父类加载器为引导类加载器。**应用类加载器(application class loader):**从应用的CLASSPATH中加载类。它的父类加载器为扩展类加载器。

    Java 9仍然保留了三层类加载器结构,不过为了支持模块系统,对它们做了一些调整。扩展机制被移除,扩展类加载器由于向后兼容性的原因被保留,不过被重命名为平台类加载器(platform class loader)。

    Bootstrap class loader 引导类加载器:定义核心Java SE和JDK模块。它是虚拟机的内置类加载器,通常表示为null,并且没有父nullPlatform class loader 平台类加载器:定义部分Java SE和JDK模块。平台类加载器可以看到所有平台类,平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类System class loader 应用或系统类加载器:定义CLASSPATH上的类和模块路径中的模块。它也被称为应用程序类加载器,与平台类加载器不同。系统类加载器通常用于定 义应用程序类路径,模块路径和JDK特定工具上的类

    类加载器的继承关系: System的父加载器为Platform, 而Platform的父加载器为Bootstrap

    ClassLoader:是负责加载类的对象 程序类加载器 ClassLoader 中的俩个方法: static ClassLoader getSystemClassLoader0): 返回用于委派的系统类加载器 СlаѕѕLоаdеr gеtРаrеnt(): 返回父类加载器进行委派

    1.5 JVM的类加载机制

    全盘负责: 就是当一个类加载器负责加载某个Cass时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除 非显示使用另外-个类加载器来载入父类委托: 就是当一个类加载器负责加载某个Class时,先让父类加载器试图加载该Class,只有在父类加载器无法加载该类 时才尝试从自己的类路径中加载该类缓存机制: 保证所有加载过的Class都会被缓存,当程序需要使用某个Class对象时,类加载器先从缓存区中搜索该Cass,只 有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存储到缓存区

    2.反射概述

    2.1 Java反射机制

    指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大增强程序的灵活性,程序不用在编译期就完成确定,在运行期还可以扩展。就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等。

    2.2 获取Class类的对象

    要通过放射去使用一个类,首先我们要获取到该类的字节码文件,也就是类型为Class类型的对象,这里有三种方式来获取Class类型的对象:

    使用类的class属性来获取该类对应的Class对象。举例: Student.class将 会返回Student类对应的Class对象调用对象的getClass0方法,返回该对象所属类对应的Class对象   该访法是Object类中的方法,所有的Java对象都可以调用该方法使用Class类中的静态forName(StringclassName),该方法需要传入字符串参数,该字符串参数的值是某 个类的全路径,也就是完整包名的路径

    2.3 反射获取构造方法并使用

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

    Constructor<?> [] getConstructors():返回所有公共构造方法对象的数组Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组Constructor< T > getConstructor(Class <?>… parameterTypes):返回单个公共构造方法对象Constructor< T > getDeclaredConstructor(Class<?> … parameterTypes):返回单个构造方法对象

    Constructor类中用于创建对象的方法

    T newInstance(Obje… initargs):根据指定的构造方法创建对象

    基本数据类也可以通过.class得到对于的Class类型 暴力反射:public void setAccessible(boolean flag): 值为true,取消访问检查。使用私有构造方法创建对象

    2.4 反射获取成员变量并使用

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

    Field[] getFields(): 返回所有公共成员变量对象的数组Field] getDeclaredFields(): 返回所有成员变量对象的数组Field getField(String name):返回单个公共成员变量对象Field getDeclaredField(String name):返回单个成员变量对象

    Field类中用于给成员变量赋值的方法

    void set(Object obj, Objectvalue):给obj对象的成员变量赋值为value

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

    Method[] getMethods(:返回所有公共成员方法对象的数组,包括继承的Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的Method getMethod(String name, Class <?>… parameterTypes):返回单个公共成员方法对象Method getDeclaredMethod(String name, Class<?> … parameterTypes):返回单个成员方法对象

    Method类中用于调用成员方法的方法

    Object invoke(Object obj, Object… args):调用obj对象的成员方法,参数是args,返回值是Object类型
    Processed: 0.008, SQL: 9