我正在尝试创建一个方法invokeMethod(String methodName, Object...args)
,该方法从当前实例上的超类调用方法。我尝试了以下实现。
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();
}
}
Run Code Online (Sandbox Code Playgroud)
这个实现的问题是,如果我尝试调用一个带有原始参数的方法,我会得到一个,NoSuchMethodException
因为它正在寻找一个参数类型与包装类等效的方法。
例如,如果我尝试调用的方法与签名line(float, float, float, float)
,试图invokeMethod("line", 50f, 50f, 50f, 50f)
,我看到类似的异常
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)
Run Code Online (Sandbox Code Playgroud)
有没有办法让我的invokeMethod
方法使用原始参数?
编辑:这里的解决方案不起作用,因为我不知道在执行我的方法时签名中到底有哪些原始类型。我希望能够执行类似的方法size(int, int)
,并line(float, float ,float ,float)
用我的方法,并在链接的解决方案不容易与这方面的工作。我看到的唯一解决方案是为超类中的每个可能的方法定义一个 if 语句,然后在链接中使用该解决方案,但我想要一种不那么乏味的方法。
当诸如10
或 之10.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();
}
}
Run Code Online (Sandbox Code Playgroud)
我这里只添加了3个案例,其他5个你可以自己添加。
这意味着您现在不能使用包装器类型参数调用方法。如果你也想调用它们,你需要
编辑:
正如 Holger 在评论中建议的那样,您也可以让 JVM 为您找到合适的方法,方法是使用
new Statement(this, methodName, args).execute();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1386 次 |
最近记录: |