java - 如何使用反射调用在可变参数中包含 null 的方法
问题描述
我的情况就像一个类包含相同的方法名称,我们正在尝试使用反射来调用,但是当其中一个参数包含 null 时似乎有问题
例如 :
package test;
public class Invoker {
public void test(String a, Integer b) {
System.out.println("String, Integer");
}
public void test(Integer a, Integer b) {
System.out.println("Integer, Integer");
}
public void invoke(String methodName, Object ...args) {
try {
Class<?>[] clazz = new Class[args.length];
int i=0;
for(Object a:args) {
clazz[i++] = a != null ? a.getClass() : null;
}
Method m = this.getClass().getMethod(methodName, clazz);
// ... Continue for invocation
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String ...args) {
Invoker invoker = new Invoker();
// happened to be null sometimes
String a = null;
Integer b = 123;
System.out.println("Trigger Normally");
invoker.test(a, b);
System.out.println("Trigger via Reflection");
invoker.invoke("test", a, b);
}
}
结果
Trigger Normally
String, Integer
Trigger via Reflection
java.lang.NoSuchMethodException: test.Invoker.test(null, java.lang.Integer)
at java.lang.Class.getMethod(Class.java:1678)
at test.Invoker.invoke(Invoker.java:21)
at test.Invoker.main(Invoker.java:42)
Argument 有时恰好为 null,但如果为 null,则会触发NoSuchMethodException
我们的方法名不是唯一的,它必须是重载结构。
解决方案
由于早期绑定,被调用的重载方法是在编译时确定的(或者如果无法确定,则会出现编译时错误)。既然你有String a = null
,编译器就可以确定你要调用test(String, Integer)
。
您的反射调用发生在运行时并且缺少null
参数中的类型信息(该方法不知道它来自 a String a
,编译器在编译时知道,但这是运行时),因此您需要提供信息是否为 nullString
或Integer
。
如果您想让反射方法使用空值(和重载方法),则需要添加一个单独的类型参数以在空值的情况下使用。例如
invoker.invoke("test", a, String.class, b, Integer.class);
如果没有额外的类型信息,你不能让它为空值工作,因为它就像调用test(null, 1)
. 在这种情况下,编译器也需要您的帮助,例如,test((Integer)null, 1)
或者test((String)null, 1)
,尝试一下。
推荐阅读
- javascript - Javascript Onclick通过附加函数传递对象
- reactjs - 如何在更新时获得反应 noUiSlider 最小最大值?
- windows - Rstudio 无法连接到 Windows 机器上启用 SSL 的 postgresql 服务器
- asp.net-mvc - 有什么方法可以在 MVC 中的另一个页面单击后退按钮中的确切数据显示上一页
- php - 在验证期间获取 Laravel 验证中的 ErrorMessage 包
- azure-log-analytics - 使用 PowerShell 将 Azure 活动日志连接到 Log Analytics 实例
- python - scrapy 503 服务在 starturl 上不可用
- android - 通过 okhttp 上传具有概率失真的图像
- sql - 查询分组中的 Oracle SQL 条件聚合函数
- angular - 如何使用 CLI 在 Ionic 中将页面添加到 app.module.ts