java回顾八股文中想起的知识点

发布于:2025-08-07 ⋅ 阅读:(18) ⋅ 点赞:(0)

java反射原理:

Java 的反射(Reflection)本质上依靠的是 JVM 在运行时保存的类的元数据(Metadata),这些元数据来自 .class 文件中的 Class 文件结构,并由 Class 对象 + java.lang.reflect 包 提供访问入口。

我给你分成几个层次解释,这样你能从底层到应用都搞明白。


1. 反射的定义

反射就是在 运行时 动态获取类的信息,并操作类的属性、方法、构造器,甚至创建对象。
它的特点是:

  • 不需要在编译时就知道具体的类

  • 运行时可以根据类名、方法名等字符串进行操作。


2. 反射依靠的底层机制

(1)Class 文件中的元数据

当你用 javac 编译 .java 源文件后,会生成 .class 文件。
这个 .class 文件遵循 Java Class File Format(Java虚拟机规范),里面包含了:

  • 类的名称、父类名称

  • 成员变量(字段)的名称、类型、修饰符

  • 方法签名(方法名、参数类型、返回值类型)

  • 注解信息

  • 常量池(字符串、类引用等)

这些信息就是 类的元数据(Metadata)


(2)JVM 的 方法区/元空间(Metaspace)

  • 当 JVM 加载类时(ClassLoader 负责),会把 .class 文件解析后,将类的元数据存储到 方法区(Java 8 以前)或元空间(Java 8 以后)

  • 这个元数据中保存了类的:

    • 字段信息

    • 方法信息

    • 构造方法信息

    • 注解信息

  • 反射就是读取这些元数据来工作的


(3)java.lang.Class

  • 每个加载到 JVM 的类,在内存中都会有一个唯一的 Class 对象表示它的类型信息。

  • Class 对象是反射的入口,你可以通过以下方式获得:

    Class<?> clazz1 = Class.forName("com.example.User");
    Class<?> clazz2 = User.class;
    Class<?> clazz3 = userInstance.getClass();
    
  • 这个 Class 对象中保存了指向元数据的引用,反射 API 就是通过它去查询和操作元数据。


(4)java.lang.reflect

  • 反射 API 主要在 java.lang.reflect 包下,比如:

    • Field(字段)

    • Method(方法)

    • Constructor(构造方法)

  • 它们提供了读写属性、调用方法、创建对象等功能。

  • 这些类会通过 native 方法调用 JVM 的底层接口(HotSpot VM 中是 C++ 实现)去访问方法区/元空间的元数据。


3. 流程图

[.java 源代码]
     ↓ 编译
[.class 字节码文件]
     ↓ 类加载器解析(ClassLoader)
[方法区/元空间存放类元数据]
     ↓
[Class对象]  ←→  java.lang.reflect API
     ↓
反射操作(获取字段/方法/构造器、实例化对象、调用方法)

4. 示例:反射依靠元数据访问类

public class User {
    private String name;
    public void sayHello() {
        System.out.println("Hello, " + name);
    }
}

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        // 1. 获取Class对象(依赖类加载器和元数据)
        Class<?> clazz = Class.forName("User");

        // 2. 创建实例
        Object obj = clazz.getDeclaredConstructor().newInstance();

        // 3. 获取字段并修改(依赖元数据)
        Field field = clazz.getDeclaredField("name");
        field.setAccessible(true);
        field.set(obj, "Tom");

        // 4. 获取方法并调用(依赖元数据)
        Method method = clazz.getDeclaredMethod("sayHello");
        method.invoke(obj); // 输出:Hello, Tom
    }
}

5. 总结

Java 反射依靠的是:

  1. .class 文件中的 类元数据(字段、方法、构造器等信息)。

  2. JVM 类加载后存储在 方法区/元空间 的类结构。

  3. Class 对象作为元数据的入口。

  4. java.lang.reflect 通过 JVM 本地方法访问元数据并操作。


💡 换句话说:
反射不是凭空出现的,它是 JVM 通过 类加载 + 元数据存储 + Class对象 + 反射API 这一整套机制支撑的。


为什么int表示范围,正数比负数少1:

因为用补码表示


网站公告

今日签到

点亮在社区的每一天
去签到