我们可以使用属性名称查找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">
现在我遍历地图和我继续从地图的每个项目,基于密钥(名称或公司),我需要调用类的相应的setter方法A例如,对于第一个项目,我得到的名称键,以便需要调用新的A ().setName。
Answer 1:
虽然这是可能使用反射来这样做,你可能会关闭使用更好的公共-BeanUtils的 。 你可以很容易地使用setSimpleProperty()
像这样的方法:
PropertyUtils.setSimpleProperty(a, entry.getKey(), entry.getValue());
假设a
IS类型的A
。
Answer 2:
如果您使用的春天 ,那么你很可能需要使用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();
这比使用反射直接,因为春天会为你做常见的类型转换更容易。 (这也将履行Java属性编辑器,所以你可以为它不处理的那些注册自定义类型转换。)
Answer 3:
使用地图把一个字段名称和它的setter方法的名称,或使用字符串连接“设置”以首字母大写propertyName的似乎是一个相当薄弱的方式调用一个setter方法。
其中,你知道类的名字,你可以通过它的属性进行迭代,并获取每个属性的setter / GetterMethod名称一个场景可以解决像下面的代码片段。
您可以从java.beans中获得内部检查/属性描述*。
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();}
Answer 4:
Reflection API
是你所需要的。 让我们假设你知道属性名和你有一个对象a
类型的A
:
String propertyName = "name";
String methodName = "set" + StringUtils.capitalize(propertyName);
a.getClass().getMethod(methodName, newObject.getClass()).invoke(a, newObject);
Ofcourse,你会被要求来处理一些例外。
Answer 5:
你可以得到这样的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());
但是,如果只为您的工程类别。 如果你有这样的扩展基类的类则class.getField(名称)将尚未工作。
你应该采取的BeanWrapper的在偷看Juffrou-反映 。 这是更好的性能比springframework的公司,并允许您向您的地图豆改造和更大量。
免责声明:我是谁开发Juffrou,反映的家伙。 如果您有关于如何使用它的任何问题,我会很乐意回应更多。
Answer 6:
这实际上是平凡的,因为有关于驼峰字段名大写的特殊规则。 按照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())
这同样适用于干将,除了布尔类型使用“是”,而不是“得到”作为前缀。
Answer 7:
我想你也许可以做到这一点与反思,一个简单的解决方案正在做的关键字符串比较,并调用适当的方法:
String key = entry.getKey();
if ("name".equalsIgnoreCase(key))
//key
else
// company
文章来源: How to identify setter method using property name?