Java中Method.invoke()参数传递严格遵循值传递机制:基本类型传数值副本,引用类型传地址副本,与普通方法调用完全一致,反射不改变语言级语义。

没有变化。Java 中通过 Method.invoke() 传递参数时,底层依然严格遵循 Java 原生的值传递机制,和普通方法调用完全一致——反射不改变语言级语义。
参数副本逻辑不变
无论是否通过反射调用,JVM 对每个实参都执行相同操作:
- 基本类型(
int、boolean等):传入的是栈中数值的完整副本 - 引用类型(
String、List、自定义对象等):传入的是堆中对象地址的副本(不是对象本身,也不是“引用变量”本身)
反射调用不绕过值传递规则
Method.invoke(obj, arg1, arg2) 中的 arg1、arg2 仍是按值传入 invoke 方法内部;而 invoke 再将这些参数“按值”转发给目标方法——整个链路没有引入引用传递或地址直接传递。
例如:
- 你传
new Person("张三"),invoke 拿到的是该对象地址的一个副本,目标方法内修改p.name = "李四",外部可见;但若在目标方法里写p = new Person("王五"),外部原变量仍指向“张三”对象 - 你传
Integer.valueOf(42),invoke 接收的是这个包装类实例的地址副本;目标方法若声明接收int,JVM 会自动拆箱——这是签名匹配阶段的类型转换,不是传递机制变更
容易混淆的点:setAccessible 和参数类型检查
看似“特殊”的行为,其实和值传递无关:
-
setAccessible(true)只是关闭 JVM 的访问控制检查,不影响参数如何被复制或传递 - 参数类型不匹配报
IllegalArgumentException,是因为反射在运行时做严格签名比对(比如期望long却给了Integer),而非改变了传递方式 - 基本类型必须匹配(
int不能用Long替代),这是反射的类型安全要求,不是值传递被削弱或增强
结论:机制稳定,理解要准
从 JDK 8 到 JDK 21(含当前时间 2026 年),Java 规范从未修改参数传递模型。反射只是在运行时动态绑定方法,它复用同一套栈帧分配与参数压栈逻辑。所谓“传对象像传引用”,本质仍是传地址副本——这点在直接调用和反射调用中完全一致。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











