我被这个问题困扰了两天。我在类测试中有一个 testN 方法列表,我将为这个类添加更多的 test* 方法。示例代码如下所示
public class Test {
public void test1(String a, int b, boolean c){
System.out.println("a="+a+" "+b+ " c="+c);
}
public void test3(Test test){
System.out.println(test.toString());
}
public void run(Object... objs){
//First way...
if(objs.length>=3){
test1((String)objs[0], (int)objs[1], (boolean)objs[2]);
}else if(objs.length <3 ){
test3((Test)objs[0]);
}
//Second way?
MethodType type1 = MethodType.methodType(void.class, String.class, int.class, boolean.class);
if(objs.length>=3){
//How to tranform first 3 elements of objs to a list (String, int, boolean)
Object[] t = Arrays.copyOfRange(objs, 0, type1.parameterCount());
test1(???);
}
MethodType type3 = MethodType.methodType(void.class, Test.class);
if(objs.length < 3 ){
}
}
public static void main(String[] args){
Test test = new Test();
test.run("String", 3, false, 5,7);
test.run(test,1);
}
}
方法 run(Object... objs)
是这个类的主要入口,它接受一个 var args 列表。在run
方法内部,根据objs的长度调用不同的test*方法(objs被识别为数组)。
我的问题是如何以第二种方式将 Object[] t
作为方法 test1
的 var args 列表传递?第一种方式是handle-write,当加入更多的test*
方法时不实用。 Object[] t
是数组,它是一个对象,而 test1
需要三个参数。我正在寻找一种可以将数组转换为用于方法调用的参数列表的方法。
最佳答案
你需要使用反射。首先,获取您的 Test.class — 这很简单,它只是 Test.class
。接下来,获取您的方法,这可以通过了解参数的类型(通过每个参数的 .getClass()
和 .getMethod(...)
方法来完成Class
或通过搜索 getMethods()
返回的数组。两者都会为您提供一个 Method
对象供您使用。最后,您可以调用使用 method.invoke(this, objs);
的方法。
编辑:关于您的评论,没有参数的列表。至少不像 java.util.List
那样。 JVM 确实将参数放在堆栈上(并且可以以任何可以想到的方式自由地这样做;在许多情况下甚至堆栈都会被优化到寄存器中)。
所以问题是,您需要 a) 知道对象的 VM 类型(可以是 int、long、float、double 或 ref 中的任何一种)和 b) 对象的位置。然后您可以通过创建一个合成字节码序列来做类似的事情(请注意,虽然这会产生有效的 JVM 字节码,但没有有效的 Java 代码可以执行此操作,除非您计算自定义类加载器)。否则,不,在 Java 中无法创建“参数列表”。
关于java - 如何将数组转换为 args 列表以在 Java 中调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28477744/