java反射调用带参方法时,参数类型必须严格匹配方法签名:基本类型用int.class、包装类型用integer.class、数组用string[].class、泛型用list.class;调用时自动装箱拆箱,但null传入基本类型参数会抛illegalargumentexception。

Java 反射调用带参方法时,关键不是“怎么传参数列表”,而是参数类型必须严格匹配方法签名中声明的参数类型,否则会抛 NoSuchMethodException 或运行时报 IllegalArgumentException。
参数类型必须和方法声明完全一致
反射查找方法用的是 Class.getMethod(String name, Class>... parameterTypes),它按参数的编译时类型(即 Class 对象)精确匹配
- 基本类型(如
int)要传int.class,不能传Integer.class - 包装类型(如
Integer)要传Integer.class,不能传int.class - 数组类型写成
String[].class,不是String.class - 泛型擦除后按原始类型匹配,比如
List<string></string>就是List.class
调用时传参要自动装箱/拆箱或显式转换
Method.invoke(Object obj, Object... args) 的 args 是 Object[],所以:
- 基本类型值会被自动装箱(
5→Integer.valueOf(5)),但前提是方法参数是包装类型 - 如果方法参数是
int,你传Integer也能成功(JVM 自动拆箱) - 但如果方法是
int,你传null就会报IllegalArgumentException(无法拆箱) - 字符串、自定义对象等引用类型直接传对应实例即可
常见错误示例与修正
假设目标方法是:public void print(int age, String name, List<string> tags)</string>
- ❌ 错误写法:
clazz.getMethod("print", Integer.class, String.class, ArrayList.class)
→ArrayList.class≠List.class;且int应该用int.class - ✅ 正确写法:
clazz.getMethod("print", int.class, String.class, List.class) - ✅ 调用时:
method.invoke(obj, 25, "张三", Arrays.asList("java", "reflect"))
处理可变参数(varargs)要特别注意
比如方法:void log(String prefix, String... msgs)
- 获取方法时仍用
String[].class:getMethod("log", String.class, String[].class) - 调用时有两种方式:
• 传数组:invoke(obj, "DEBUG", new String[]{"a", "b"})
• 或直接展开(JVM 自动包装):invoke(obj, "DEBUG", "a", "b") - 但如果第一个参数也是
String,而你只传两个String,JVM 会把第二个当 varargs 元素——不会报错,但语义可能错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











