如何识别使用属性名称的setter方法?
我们可以使用属性名称找到setter方法名称吗?如何识别使用属性名称的setter方法?
我已动态生成map<propertyName,propertyValue>
通过使用从地图键(这是propertyName的)我需要调用为对象相应的方法,并从地图传递值(这是的PropertyValue)。
class A {
String name;
String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
}
我的地图包含两个项目:
map<"name","jack">
map<"company","inteld">
现在我遍历地图和我继续从地图上每个项目的基础上,重点(名称或公司),我需要适当调用例如A类的设定器方法 对于第一项我得到的名称作为关键,所以需要调用新的A()。setName。
我想你也许可以做到这一点与反思,一个简单的解决方案正在做的关键字符串比较,并调用适当的方法:
String key = entry.getKey();
if ("name".equalsIgnoreCase(key))
//key
else
// company
虽然这是可能使用反射来这样做,你可能会更好关闭使用commons-beanutils。你可以很容易地使用setSimpleProperty()
方法,像这样:
PropertyUtils.setSimpleProperty(a, entry.getKey(), entry.getValue());
假设a
为A
类型。
不错的建议! – vikingsteve 2013-02-27 15:00:48
Reflection API
是你需要的。让我们假设你知道属性的名字,你有A
类型的对象a
:
String propertyName = "name";
String methodName = "set" + StringUtils.capitalize(propertyName);
a.getClass().getMethod(methodName, newObject.getClass()).invoke(a, newObject);
Ofcourse,你会被要求来处理一些例外。
例外,是的,但也缓存了反射查找的结果。还要注意,这个建议要求setter采用一个已知的参数类型('String'),如果你只使用已知的参数类型,这很好,但如果你使用其他对象可能会出错(尤其是涉及继承的地方) )。这就是为什么像beanutils或Spring的BeanWrapper这样的东西值得一看。 – ig0774 2013-02-27 15:19:21
如果您使用Spring,那么您可能需要使用BeanWrapper
。 (如果没有,你可能会考虑使用它)。
Map map = new HashMap();
map.put("name","jack");
map.put("company","inteld");
BeanWrapper wrapper = new BeanWrapperImpl(A.class);
wrapper.setPropertyValues(map);
A instance = wrapper.getWrappedInstance();
这比直接使用反射更容易,因为Spring会为你做常见的类型转换。 (这也将履行Java属性编辑器,所以你可以为它不处理的那些注册自定义类型转换。)
你可以得到的setter方法是这样的:
A a = new A();
String name = entry.getKey();
Field field = A.class.getField(name);
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
Method setter = bw.getBeanClass().getMethod(methodName, (Class<?>) field.getType());
setter.invoke(a, entry.getValue());
,但只会工作为你的A班。如果你有一个扩展基类的类,那么class.getField(name)就不能工作了。
你应该看一下在Juffrou-reflect的BeanWrapper。它比Springframework更具性能,并允许你进行地图bean转换以及更多其他功能。
声明:我是开发Juffrou反射的人。如果您对如何使用它有任何疑问,我会很乐意回复。
使用映射来放置字段名称及其Setter方法名称,或使用字符串串联来“设置”第一个字母大写的propertyName似乎是一个很弱的方法来调用Setter方法。
一个场景,其中您知道类名称,并且您可以遍历其属性并获取每个Property的Setter/GetterMethod Name,可以像下面的代码片段一样解决。
您可以从java.beans。*获取Introspector/Property Descriptor;
try {
Animal animal = new Animal();
BeanInfo beaninfo = Introspector.getBeanInfo(Animal.class);
PropertyDescriptor pds[] = beaninfo.getPropertyDescriptors();
Method setterMethod=null;
for(PropertyDescriptor pd : pds) {
setterMethod = pd.getWriteMethod(); // For Setter Method
/*
You can get Various property of Classes you want.
*/
System.out.println(pd.getName().toString()+ "--> "+pd.getPropertyType().toString()+"--Setter Method:->"+pd.getWriteMethod().toString());
if(setterMethod == null) continue;
else
setterMethod.invoke(animal, "<value>");
}
}catch(Exception e) {e.printStackTrace();}
海事组织这是正确的方式来匹配一个字段与其setter,使用香草Java。 – JN01 2016-10-26 13:57:38
这实际上是非常平凡的,因为有关于camelCase字段名称大写的特殊规则。根据JavaBeans API(第8.8节),如果字段名称的前两个字符都是大写字母,则该字段不会大写。
因此
-
index
变得Index
- >setIndex()
-
xIndex
撑作为xIndex
- >setxIndex()
-
URL
撑作为URL
- >setURL()
执行此将转换的代码成为如下:
/**
* Capitalizes the field name unless one of the first two characters are uppercase. This is in accordance with java
* bean naming conventions in JavaBeans API spec section 8.8.
*
* @param fieldName
* @return the capitalised field name
* @see Introspector#decapitalize(String)
*/
public static String capatalizeFieldName(String fieldName) {
final String result;
if (fieldName != null && !fieldName.isEmpty()
&& Character.isLowerCase(fieldName.charAt(0))
&& (fieldName.length() == 1 || Character.isLowerCase(fieldName.charAt(1)))) {
result = StringUtils.capitalize(fieldName);
} else {
result = fieldName;
}
return result;
}
设定器的名称可以然后通过预先找到在它的前面“组”:"set" + capatalizeFieldName(field.getName())
这同样适用于吸气剂,不同之处在于布尔类型使用“是”,而不是“获取“作为前缀。
这不是一个可维护的方法,只能用于快速和简单的初始化。 – 2013-02-27 15:24:05