java 如何使用属性名称识别setter方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15115072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to identify setter method using property name?
提问by Vishal Jagtap
Can we find setter method name using property name?
我们可以使用属性名称找到 setter 方法名称吗?
I have a dynamically generated map<propertyName,propertyValue>
我有一个动态生成的 map<propertyName,propertyValue>
By using the key from map (which is propertyName) I need to invoke the appropriate setter method for object and pass the value from map (which is propertyValue).
通过使用 map 中的键(propertyName),我需要为对象调用适当的 setter 方法并传递 map 中的值(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;
}
}
My map contain two items:
我的地图包含两个项目:
map<"name","Hyman">
map<"company","inteld">
Now I am iterating the map and as I proceed with each item from map, based on key (either name or company) I need to call appropriate setter method of class A e.g. for first item I get name as key so need to call new A().setName.
现在我正在迭代地图,当我根据键(名称或公司)处理地图中的每个项目时,我需要调用 A 类的适当 setter 方法,例如,对于第一项,我将名称作为键,因此需要调用 new A ().setName。
回答by ig0774
Although this is possible to do using reflection, you might be better off using commons-beanutils. You could easily use the setSimpleProperty()
method like so:
尽管使用反射可以做到这一点,但您最好使用commons-beanutils。您可以轻松地使用该setSimpleProperty()
方法,如下所示:
PropertyUtils.setSimpleProperty(a, entry.getKey(), entry.getValue());
Assuming a
is of type A
.
假设a
是类型A
.
回答by Alan Krueger
If you use Springthen you'll likely want to use the BeanWrapper
. (If not, you might consider using it.)
如果您使用Spring,那么您可能想要使用BeanWrapper
. (如果没有,您可以考虑使用它。)
Map map = new HashMap();
map.put("name","Hyman");
map.put("company","inteld");
BeanWrapper wrapper = new BeanWrapperImpl(A.class);
wrapper.setPropertyValues(map);
A instance = wrapper.getWrappedInstance();
This is easier than using reflection directly because Spring will do common type conversions for you. (It will also honor Java property editors so you can register custom type converters for the ones it doesn't handle.)
这比直接使用反射更容易,因为 Spring 会为您进行常见的类型转换。(它还支持 Java 属性编辑器,因此您可以为它不处理的那些注册自定义类型转换器。)
回答by Mitesh Manani
Using a Map to put a Field Name and its Setter Method Name, or using a String Concatenation to "set" with a First Letter Capitalized propertyName seems to be a Pretty weak approach to call a Setter Method.
使用 Map 来放置字段名称及其 Setter 方法名称,或使用字符串连接来“设置”首字母大写的 propertyName 似乎是调用 Setter 方法的一种非常弱的方法。
A scenario wherein you know the Class name and you can iterate through its properties and get each Property's Setter/GetterMethod Name can be solved like the below Code Snippet.
在您知道类名称并且您可以遍历其属性并获取每个属性的 Setter/GetterMethod 名称的情况下,可以像下面的代码片段一样解决。
You can get the Introspector / Property Descriptor from java.beans.*;
您可以从 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();}
回答by ogzd
Reflection API
is what you need. Let's assume that you know the property name and you have an object a
of type A
:
Reflection API
是你所需要的。假设您知道属性名称并且您有一个a
类型为的对象A
:
String propertyName = "name";
String methodName = "set" + StringUtils.capitalize(propertyName);
a.getClass().getMethod(methodName, newObject.getClass()).invoke(a, newObject);
Ofcourse, you will be asked to handle some exceptions.
当然,你会被要求处理一些异常。
回答by Martins
You could get the setter method like this:
你可以得到这样的 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());
But it would only work for your A class. If you had a class that extended a base class then the class.getField(name) would not work already.
但它只适用于你的 A 类。如果您有一个扩展基类的类,那么 class.getField(name) 将无法工作。
You should take a peek at the BeanWrapper in Juffrou-reflect. It's more performant than Springframework's and allows you to to your map-bean transformation and a lot more.
您应该看看Juffrou-reflect中的 BeanWrapper 。它比 Springframework 的性能更高,并允许您进行 map-bean 转换等等。
Disclaimer: I am the guy who develops Juffrou-reflect. And if you have any questions on how to use it, i'll be more than happy to respond.
免责声明:我是开发 Juffrou-reflect 的人。如果您对如何使用它有任何疑问,我将非常乐意回答。
回答by kemosabe
This is actually nontrivial, since there are special rules about capitalisation of camelCase field names. As per the JavaBeans API (section 8.8), the field is not capitalised if either of the first two characters of the field name are capitals.
这实际上很重要,因为有关于camelCase 字段名称大小写的特殊规则。根据 JavaBeans API(第 8.8 节),如果字段名称的前两个字符之一是大写,则该字段不大写。
Thus
因此
index
becomesIndex
->setIndex()
xIndex
stays asxIndex
->setxIndex()
URL
stays asURL
->setURL()
index
变成Index
->setIndex()
xIndex
保持为xIndex
->setxIndex()
URL
保持为URL
->setURL()
The code to perform this conversion would be as follows:
执行此转换的代码如下:
/**
* 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;
}
The name of the setter can then be found by prepending "set" in front of it: "set" + capatalizeFieldName(field.getName())
然后可以通过在它前面加上“set”来找到 setter 的名称: "set" + capatalizeFieldName(field.getName())
The same applies to getters, except that boolean types use "is" instead of "get" as a prefix.
这同样适用于 getter,除了布尔类型使用“is”而不是“get”作为前缀。
回答by Shadi A
I think you can probably do that with reflection, a simpler solution is doing string comparison on the key and invoke the appropriate method:
我认为您可以通过反射来做到这一点,一个更简单的解决方案是对键进行字符串比较并调用适当的方法:
String key = entry.getKey();
if ("name".equalsIgnoreCase(key))
//key
else
// company