在我正在编写的模型中,我有一个带有签名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?
发布于 2010-07-08 23:22:44
您可以将您的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的源代码,您可以将其更改为采用装箱的整数而不是整数-开销通常可以忽略不计。
发布于 2010-07-08 23:24:26
有没有办法说服这个反射代码将5(或者我传入的任何整数)作为一个整数传递,而不进行装箱?
当你的方法签名是Object newValue的时候就不会了,因为int永远不能是Object。保持方法泛型的一种方法是让调用者显式地传入类型,即:
protected void setModelProperty(String propertyName, Object newValue, Class type) {或者,您可以测试newValue的类型,以确定它是否是原语包装器,在这种情况下,可以同时查找该方法的原语和包装版本。但是,当用户传入null时,这将不起作用。实际上,在这种情况下,该方法根本不起作用。
发布于 2010-07-08 23:24:26
当调用setModelProperty()时,newValue被装箱为整数。这是唯一可以调用它的方法;'int‘不是instanceof对象。newValue.getClass()返回“整数”,因此对getMethod()的调用失败。
如果你想在这里使用原语,你需要一个特殊版本的setModelProperty。或者,您可以编写一个方法setFoo(整数)。
或者更一般地说,你可以这样写:
if (newValue.getClass()==Integer.class) {
// code to look for a method with an int argument
}https://stackoverflow.com/questions/3205098
复制相似问题