我正在尝试使用Java中的反射来调用方法,但是当我调用invoke方法时,会出现异常。这是我的代码:
public void start() {
try {
ServerSocket server = new ServerSocket(port);
while(true) {
Socket s = server.accept();
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
Class<?> myClass = Class.forName(vmi.getClass().toString().split(" ")[1]);
ArrayList<Object> array = new ArrayList();
Constructor<?> cons = myClass.getConstructor(new Class<?>[] {});
String method = null;
for(Method m : myClass.getMethods()) {
method = in.readObject().toString();
if(m.getName().equals(method)) {
Type return_type = m.getGenericReturnType();
for(Type types: m.getGenericParameterTypes()) {
array.add(in.readObject());
}
System.out.println(return_type);
if (return_type.toString().equals("void")) {
m.invoke(vmi, (Object)array);
}
break;
}
}
}
} catch (IOException | ClassNotFoundException | NoSuchMethodException
| SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Skeleton Exception "+ e.toString());
}
}
这是例外:
java.lang.IllegalArgumentException:参数数量错误
我还尝试使用空对象调用该方法,并且异常继续
m.invoke(vmi, new Object(), new Object());
顺便说一下,变量 vmi 和 port 在构造函数中初始化。
答案 0 :(得分:1)
Method.invoke
方法的签名是:
public Object invoke(Object obj, Object... args)
这是语法糖(如果您不通过varargs):
public Object invoke(Object obj, Object[] args)
但是,您正在传递(Object,Object)
->这将把第二个对象作为varargs的单个参数,因此编译器会将您的调用转换为m.invoke(vmi, new Object[] { array })
。
使代码复杂化的事实是,您有一个名为array
的变量,但其类型实际上是ArrayList
,它不是数组。
您可以将代码更改为:
m.invoke(vmi, array.toArray());
这会将您的参数作为整个varargs参数args
传递,而不是作为varargs数组中的单个元素传递。