Java反射API并调用具有可变数量参数的方法

时间:2011-10-30 22:11:55

标签: java reflection methods parameter-passing invoke

当我使用Java Reflection API调用接受可变数量参数的方法时,我在尝试解决这种情况时遇到问题。每当我尝试这样做时,我都会得到一个“NoSuchMethodException”。

我要调用的方法声明:

public void AddShow(String movieName, String cinemaName, String... days) {
}

执行调用的方法的代码:

public void Exec(String command){
    try {
        String[] words = command.split(" ");
        String commandName = words[0];
        Class<? extends UserInterface> thisClass = (Class<? extends UserInterface>)getClass();
        Class<String>[] par = new Class[words.length-1];
        String[] params = new String[words.length-1];
        for(int i = 1; i< words.length; i++){
            params[i-1] = words[i];
            try {
                par[i-1] = (Class<String>) Class.forName("java.lang.String");
            } catch (ClassNotFoundException e) {
                System.out.println("If this shows up, something is siriously wrong... Waht have you done?!");
            }
        }
        Method method;
        if(par.length != 0) {
            method = thisClass.getMethod(commandName, par);
            method.invoke(new UserInterface(CinemaDb), (Object[])params);
        } else {
            method = thisClass.getMethod(commandName);
            method.invoke(new UserInterface(CinemaDb));
        }
    } catch (SecurityException e) {
        System.out.println("Security error, sry again.");
    } catch (NoSuchMethodException e) {
        System.out.println("Wrong command, try again (check the parameters)!");
    } catch (IllegalAccessException e) {
        System.out.println("You don't have access rights, try again.");
    } catch (IllegalArgumentException e) {
        System.out.println("Wrong arguments, try again.");
    } catch (InvocationTargetException e) {
        System.out.println("Invocation error, try again.");
    }
}

如果您知道如何更改我的Exec方法来解决此问题,我将非常感激。

谢谢!

3 个答案:

答案 0 :(得分:4)

Java中的varargs是通过数组实现的,因此参数为String.class, String.class, and String[].class

答案 1 :(得分:3)

持有参数的Object[]应该有两个String参数和String[],你正在通过一个公寓String[]

答案 2 :(得分:3)

varargs部分在编译后表示为String[],因此请使用String[].class

在你的情况下,它会有点困难,因为在varargs之前你无法准确知道有多少参数。因此,如果你调用showFoo str1 str2 str3 str4,你就无法知道varargs之前有多少字符串参数。

因此,您可以在命令字符串中放置分隔符,这将告诉解析器将String[].class添加到何处。另一种选择是简单地调用getMethods()并仅通过其名称获取所需的方法(迭代并比较名称)。但是你将无法使用重载。

那就是说,我不认为为反射执行提供这样一个特殊格式的字符串是非常好的(除非它来自外部系统,但它可能是一个安全问题)