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

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:

因为用补码表示

相关推荐
wefg15 分钟前
【C++】IO流
开发语言·c++
aloha_7896 分钟前
联易融测开面试准备
java·python·面试·单元测试
s***46987 分钟前
【SpringBoot篇】详解Bean的管理(获取bean,bean的作用域,第三方bean)
java·spring boot·后端
"菠萝"12 分钟前
C#知识学习-020(访问关键字)
开发语言·学习·c#
动亦定1 小时前
页面导出大量数据导致响应超时解决方案
java·mysql
箫笙默1 小时前
JS基础 - 正则笔记
开发语言·javascript·笔记
学历真的很重要1 小时前
LangChain V1.0 Short-term Memory 详细指南
后端·python·语言模型·面试·langchain·agent·ai编程
xxp43211 小时前
Qt 网络编程 TCP通信
开发语言·qt
q***06291 小时前
解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域
java·前端·spring
还是鼠鼠1 小时前
Redisson实现的分布式锁能解决主从一致性的问题吗?
java·数据库·redis·分布式·缓存·面试·redisson