【问题标题】:Unknown number of arguments when invoking a reflection method调用反射方法时参数数量未知
【发布时间】:2019-01-26 11:40:31
【问题描述】:

我正在创建一个根据所选图像特征显示按钮的 GUI。 Let's say image A has the characteristics 1, 2 and 3, so when selected buttons that implements filters for the characteristics 1, 2 and 3 are added to my pannel.

我希望过滤器是可以轻松添加到代码中的方法,因此我使用反射来处理特征,以便为每个图像获取正确的方法。

当一个按钮被添加到 GUI 中时,它需要一个动作监听器,并在动作监听器中调用它的方法。

如果过滤器方法有参数,则一组文本字段也会添加到 GUI 中,以便收集参数。

当方法没有参数时,调用工作正常,添加文本字段以及通过这些 TF 捕获参数也很好。

问题是:使用未知大小的列表是否可以将此列表用作反射调用的参数?

Image 1 shows the GUI with no image selected, when a image is selected the buttons are added and the GUI will look like 2.

public class Filters(){
    @Name("Decompose")  
    public void decompose() {
        ...decompose the image
    }

    @Name("Weighted Blur")
    public void blurImage(@ParamName("Weight") int weight, @ParamName("Radius") int radius) {
        ...blur the image
    }
}

public class Control(){
    public void addFilterFunctions(ArrayList<Method> applicableMethods) {
        for(Method m : applicableMethods) {
            addButton(m);
        }
    }   
}


public void addButton(Method m) {       
    JButton newButton = new JButton(m.getAnnotation(Name.class).value());
    newButton.addActionListener(genericListener(m, newButton, methodFields));
}

private ActionListener genericListener(Method m, JButton b, ArrayList<JTextField> methodFields) {
    return listener ->{
        try {           
            int[] params = new int[methodFields.size()];
            for(int i =0; i<methodFields.size();i++) {
                params[i] = Integer.parseInt(methodFields.get(i).getText());
            }   

            m.invoke(filters, params);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    };
}

如您所见,我正在从添加到 JPanel 的 textFields 中收集参数,并从中创建一个 int[]。

但似乎调用方法将 Object... objs 作为参数,据我了解,这是一个列表,但我收到“java.lang.IllegalArgumentException: wrong number of arguments”错误。

【问题讨论】:

    标签: java reflection


    【解决方案1】:

    Object... 实际上与Object[] 相同,因此您需要传递Object[] 才能成功:

    Object[] params = new Object[methodFields.size()];
    for (int i = 0; i < methodFields.size(); i++) {
        params[i] = Integer.parseInt(methodFields.get(i).getText());
    }
    

    【讨论】:

    • 我无法从 int[] 转换为 Object[]。甚至做 Object[] params = new Object[methodFields.size()];我仍然收到“参数数量错误”的错误。
    • @FelipeHogrefeBento 你说得对,我更新了我的答案。
    • 还是一样:java.lang.IllegalArgumentException:参数数量错误
    • 该消息是不言自明的,filters 方法接收的参数少于您当前在 params 数组中传递的参数。
    • 最后 methodFields 没有正常工作,感谢您的时间。
    【解决方案2】:

    试试这个:

    编写采用字符串数组并让它们调用您的过滤器方法的方法。

    例如blurImageWrapper:

    public void blurImageWrapper(String[] params) {
        if (params.length == 2) {
            int weight = Integer.parseInt(params[0]);
            int radius = Integer.parseInt(params[1]);
            blurImage(weight, radius);
        }
    }
    
    @Name("Weighted Blur")
    public void blurImage(@ParamName("Weight") int weight, @ParamName("Radius") int radius) {
        ...blur the image
    }
    

    您将使用反射调用包装器方法并将String[] 的单个参数传递给它。您有一个文本字段列表,因此您可以轻松获得String[]。如果您认为这样更方便,也可以使用ArrayList&lt;String&gt;

    如果您的所有过滤器都接受 int 参数,那么您可以将字符串数组更改为 int 数组,并传递解析后的 int:

    public void blurImageWrapper(int[] params) {
        if (params.length == 2) {
            blurImage(params[0], params[1]);
        }
    }
    

    【讨论】:

    • 问题在于增加了复杂性。想法是,只需编写过滤器方法,只需添加正确的注释,该方法就可用于接口。但如果没有其他方法,我将不得不使用此解决方法。
    • @FelipeHogrefeBento 好吧,从技术上讲,您不需要其他方法。您总是可以让过滤器方法本身接受一个 int 数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多