【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() |

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

核心结论

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

相关推荐
Q_Q196328847510 小时前
python+vue的在线租房 房屋租赁系统
开发语言·vue.js·spring boot·python·django·flask·node.js
RealmElysia10 小时前
CoAlbum 引入ES
java·elasticsearch
せいしゅん青春之我10 小时前
[JavaEE初阶]网络协议-状态码
java·网络协议·http
shepherd11110 小时前
JDK源码深潜(一):从源码看透DelayQueue实现
java·后端·代码规范
天天摸鱼的java工程师10 小时前
SpringBoot + OAuth2 + Redis + MongoDB:八年 Java 开发教你做 “安全不泄露、权限不越界” 的 SaaS 多租户平台
java·后端
东巴图10 小时前
分解如何利用c++修复小程序的BUG
开发语言·c++·bug
鹿里噜哩10 小时前
Nacos跨Group及Namespace发现服务
java·spring cloud
祁同伟.10 小时前
【C++】二叉搜索树(图码详解)
开发语言·数据结构·c++·容器·stl
恒者走天下10 小时前
AI智能网络检测项目(cpp c++项目)更新
开发语言·c++
沐浴露z10 小时前
【JVM】详解 对象的创建
java·jvm