我正在编写的模型中具有签名public void setFoo(int newFoo)的方法。我正在使用以下代码从控制器中调用它:

protected void setModelProperty(String propertyName, Object newValue) {

    for (AbstractModel model: registeredModels) {
        try {
            Method method = model.getClass().
                getMethod("set"+propertyName, new Class[] {
                                                  newValue.getClass()
                                              }
                         );
            method.invoke(model, newValue);

        } catch (Exception ex) {
            //  Handle exception.
            System.err.println(ex.toString());
        }
    }
}

controller.setModelProperty("Foo",5);这样调用此方法会导致引发异常:java.lang.NoSuchMethodException: foo.bar.models.FooModel.setFoo(java.lang.Integer) -好像int被装箱为Integer,这与setFoo的签名不匹配。

有没有办法说服此反射代码以整数形式传递5(或我传递的任何int),而无需装箱?还是我必须在模型中创建public void setFoo(Integer newFoo)并明确取消装箱,然后调用原始setFoo?

最佳答案

您可以将setModelProperty专门用于您希望与之配合使用的任何原语:

protected void setModelProperty(String propertyName, int newValue) { /* ... */ }

另外,您可以在newValue上使用instanceof来检查盒装原语:
Class[] classes;
if (newValue instanceof Integer) {
  classes = new Class[] { int.class };
} else if (newValue instanceof Double) {
  /* etc...*/
} else {
  classes = new Class[] {newValue.getClass() };
}

或者最后,如果您有setFoo的源代码,则可以将其更改为采用盒装Integer而不是int-开销通常可以忽略不计。

10-05 19:38