gpt4 book ai didi

java - 如何使用反射来调用带有原始参数的方法?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:00:50 25 4
gpt4 key购买 nike

我正在尝试创建一个方法 invokeMethod(String methodName, Object...args),它从当前实例的父类(super class)中调用一个方法。我尝试了以下实现。

    public void invokeMethod(String methodName, Object...args) {
//Array to hold the classes of the arguments
Class<?>[] classes = new Class<?>[args.length];
//Initialize each class in the array to the class of each argument
for(int i = 0; i < args.length; i++)
classes[i] = args[i].getClass();
try {
//find the method
Method m = this.getClass().getMethod(methodName, classes);
//invoke the method
m.invoke(this, args);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}

此实现的问题是,如果我尝试调用带有原始参数的方法,我会得到一个 NoSuchMethodException,因为它正在寻找一个带有参数类型为等效包装类的方法。

例如,如果我尝试通过尝试 invokeMethod("line", 50f, 50f, 50f, 50f 来调用带有签名 line(float, float, float, float) ),我得到一个类似于

的异常
java.lang.NoSuchMethodException: DynamicSketch.line(java.lang.Float, java.lang.Float, java.lang.Float, java.lang.Float)
at java.base/java.lang.Class.getMethod(Class.java:2109)
at DynamicSketch.invokeMethod(DynamicSketch.java:32)
at DynamicSketch.setup(DynamicSketch.java:19)
at processing.core.PApplet.handleDraw(PApplet.java:2412)
at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)

有没有办法让我的 invokeMethod 方法使用原始参数?

编辑:解决方案here不起作用,因为在执行我的方法时我不知道签名中到底有哪些原始类型。我希望能够使用我的方法和链接中的解决方案执行 size(int, int)line(float, float ,float ,float) 等方法不容易使用这个。我看到的唯一解决方案是为父类(super class)中的每个可能方法定义一个 if 语句,然后在链接中使用该解决方案,但我想要一种不那么乏味的方法。

最佳答案

1010.0f 等参数被传递到方法中时,它们会自动包装,因为参数类型是 Object....

因此,您需要检查这些包装器类型并解包它们。您的 for 循环可能如下所示:

for(int i = 0; i < args.length; i++) {
if (args[i].getClass() == Integer.class) {
classes[i] = int.class;
} else if (args[i].getClass() == Float.class) {
classes[i] = float.class;
} else if (args[i].getClass() == Double.class) {
classes[i] = double.class;
} else {
classes[i] = args[i].getClass();
}
}

我这里只添加了3个案例,你可以自己添加另外5个。

这意味着您现在不能调用带有包装器类型参数的方法。如果你也想调用它们,你需要

  1. 解包所有类型的包装器
  2. 尝试找到那些非包装类型的方法
  3. 如果没有找到,重新打包
  4. 找到使用包装器类型的方法。

编辑:

正如 Holger 在评论中所建议的,您还可以让 JVM 找到适合您的方法,方法是使用

new Statement(this, methodName, args).execute();

Docs for the Statement class.

关于java - 如何使用反射来调用带有原始参数的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53908254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com