【Java初学基础10】一文讲清反射

1. 什么是反射

反射(Reflection)是 Java 提供的一种在运行时动态获取类的信息,并能操作类的属性和方法的机制 。

通过反射,你可以在不知道对象具体类型的情况下,操作它的属性、方法、构造函数等。

使用idea时的自动提示就是依赖了反射机制。

反射的核心是**java.lang.reflect** 包。

字节码文件的本质

  • class 文件是 跨平台的中间表示形式,里面存放着:

    • 类的元信息(类名、父类、接口等)

    • 成员变量信息

    • 方法的字节码指令

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

我们可以通过反射获取这些信息。

所以 Java 实现了"一次编译,到处运行":

  • Windows、Linux、Mac 各自有 JVM,能识别同样的 .class 文件并执行。

2. 反射的主要功能

获取类的字节码信息

java 复制代码
Class<?> clazz = Class.forName("java.util.ArrayList");

三种获取方式:

Class.forName("全限定类名")

类名.class

对象.getClass()
  1. 获取类的信息

    • 类名:clazz.getName()、clazz.getSimpleName()

    • 包名:clazz.getPackage()

  2. 获取构造方法

    java 复制代码
    Constructor<?>[] constructors = clazz.getConstructors(); // 公共构造方法 Constructor<?> constructor = clazz.getDeclaredConstructor(String.class); // 指定构造器
    java 复制代码
    getConstructors()
    获取 所有 public 构造方法。
    
    getDeclaredConstructors()
    获取 所有构造方法(包括 private、protected、default、public)。
    
    getConstructor(Class<?>... parameterTypes)
    获取 指定参数类型的 public 构造方法。
    
    getDeclaredConstructor(Class<?>... parameterTypes)
    获取 指定参数类型的构造方法(不管访问修饰符)。
  3. 获取字段(成员变量)

    java 复制代码
    Field[] fields = clazz.getDeclaredFields(); // 所有字段 
    Field field = clazz.getDeclaredField("name"); 
    field.setAccessible(true); // 允许访问 
    private field.set(obj, "Tom"); // 给字段赋值
  4. 获取方法

    java 复制代码
    Method[] methods = clazz.getDeclaredMethods(); 
    Method method = clazz.getDeclaredMethod("setName", String.class);
     method.invoke(obj, "Tom"); // 调用方法
  5. 操作对象

    Object obj = clazz.getDeclaredConstructor().newInstance(); // 创建对象

总结:


  • public 构造方法 :用 getConstructors() 或 getConstructor(...)。

  • 所有构造方法(包括 private) :用 getDeclaredConstructors() 或 getDeclaredConstructor(...),并且要 setAccessible(true) 才能使用。(暴力反射,不管是不是private)


  • 获取成员变量:

    • getField → public 字段(含继承)

    • getDeclaredField → 本类所有字段(private/protected/public/默认)

  • 操作 private 字段:

    • setAccessible(true)
  • 获取/修改值:

    • get(obj) / set(obj, value)
  • 反射可以获取字段名、类型、注解信息等,非常灵活,但性能比直接访问慢一些。


反射的应用场景

应用方向 案例 技术体现

|-------|-----------|-------------------------------------|
| 动态类加载 | 插件系统、工厂模式 | Class.forName() + newInstance() |

|--------|-------------|-------------------|
| 动态方法调用 | MVC 框架、测试工具 | Method.invoke() |

|--------|-----------------|---------------------|
| 动态字段访问 | ORM 框架、JSON 序列化 | Field.get()/set() |

|------|--------------|-----------------------------------|
| 注解解析 | Spring、JUnit | isAnnotationPresent(), 反射扫描类/方法 |

|------|---------|----------------------------|
| 动态代理 | AOP、RPC | Proxy.newProxyInstance() |

|------|------------|----------------|
| 配置驱动 | 任务调度、自动化脚本 | 结合反射解析配置执行类/方法 |

✅ 核心结论 :

反射的最大价值是 通用性和灵活性 ,它允许程序在运行时动态处理类、对象和方法,解耦、框架化、插件化、自动化。

相关推荐
weixin_307779134 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
一水鉴天7 小时前
映射、哈希表与哈斯图:计算机科学的三种基线 20261003(元宝)
开发语言·人工智能
Frank_refuel7 小时前
C++11之一场名为“搬家”的 C++ 之旅
开发语言·c++
Wang's Blog8 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
2601_962071579 小时前
类变量和全局变量的查找路径有什么区别?
开发语言·python
\光辉岁月/10 小时前
5.java-数组
java·开发语言
Java后端的Ai之路10 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
谢亮_vipxieliang10 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
时间的拾荒人10 小时前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试
郑州光合科技余经理10 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程