我需要使用反射调用类的setter方法,代码如下:
try {
Method method = myObj.getClass().getMethod("set" + fieldName, new Class[] { value.getClass() });
method.invoke(myObj, value);
} catch (Exception ex) {
ex.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
的value
是一个ArrayList
以及设置器方法如下:
public void setNames(List<String> names){
this.names = names;
}
Run Code Online (Sandbox Code Playgroud)
java.lang.NoSuchMethodException
运行此代码时抛出A ,但当setter方法参数类型更改为ArrayList
from时List
,执行正常.有没有办法将setter方法参数保持在超类型中并且仍然使用反射而无需在从类中获取方法时手动给出参数的类型?
Ana*_*and 49
你可以使用BeanUtils:
步骤1
Customer customer = new Customer();
Run Code Online (Sandbox Code Playgroud)
第2步
BeanUtils.setProperty(customer,"firstName","Paul Young");
Run Code Online (Sandbox Code Playgroud)
您可以使用反射迭代所有类成员并相应地设置值,假设客户对象具有:
private String firstName;
// Getter and Setter are defined
Run Code Online (Sandbox Code Playgroud)
el.*_*omo 46
如果您碰巧使用spring框架,则可以使用PropertyAccessorFactory来检索PropertyAccessor接口的实现:
PropertyAccessor myAccessor = PropertyAccessorFactory.forDirectFieldAccess(object);
// set the property directly, bypassing the mutator (if any)
myAccessor.setPropertyValue("someProperty", "some value");
Run Code Online (Sandbox Code Playgroud)
如果您需要使用其getter和setter访问您的属性,则可以使用以下forBeanPropertyAccess
方法:
PropertyAccessor myAccessor = PropertyAccessorFactory.forBeanPropertyAccess(object);
// a `setSomeProperty()` method will be used
myAccessor.setPropertyValue("someProperty", "some value");
Run Code Online (Sandbox Code Playgroud)
use*_*421 23
与其他答案相反,有一个非常简单的解决方案.见java.beans.Statement
.它为您提供了一种执行任意反射代码的方法,而无需担心实际与正式类型(以及其他一些事情).
有一个简单的解决方案,但这种简单性是以性能为代价的。
我正在使用这个怪物:
public static Method findMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException {
// First try the trivial approach. This works usually, but not always.
try {
return clazz.getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException ex) {
}
// Then loop through all available methods, checking them one by one.
for (Method method : clazz.getMethods()) {
String name = method.getName();
if (!methodName.equals(name)) { // The method must have right name.
continue;
}
Class<?>[] acceptedParameterTypes = method.getParameterTypes();
if (acceptedParameterTypes.length != parameterTypes.length) { // Must have right number of parameters.
continue;
}
boolean match = true;
for (int i = 0; i < acceptedParameterTypes.length; i++) { // All parameters must be right type.
if (null != parameterTypes[i] && !acceptedParameterTypes[i].isAssignableFrom(parameterTypes[i])) {
match = false;
break;
}
if (null == parameterTypes[i] && acceptedParameterTypes[i].isPrimitive()) { // Accept null except for primitive fields.
match = false;
break;
}
}
if (match) {
return method;
}
}
// None of our trials was successful!
throw new NoSuchMethodException();
}
Run Code Online (Sandbox Code Playgroud)
parameterTypes
是你从你得到的value.getClass()
。其中部分或全部也可以为空。然后它们被视为任何非原始参数字段的匹配。
即使这也不是完美的:如果有多个多态性合适的方法,但没有一个完全匹配,则返回的方法是任意选择的(clazz.getMethods()
采用返回数组中的第一个匹配项)。此行为不同于 Java 语言行为,其中始终使用“最接近的匹配”。
如果通过名称获取方法就足够了(即,如果名称匹配,则假设参数是合适的),那么您可以使用更简单(并且更快)的方式进行管理:
public static Method findMethod(Class<?> clazz, String methodName) {
for (Method method : clazz.getMethods()) {
if (method.getName().equals(methodName)) {
return method;
}
}
throw new NoSuchMethodException();
}
Run Code Online (Sandbox Code Playgroud)
为了进一步提高它,可以考虑某种缓存。