如何使用属性名识别setter方法?

时间:2013-02-27 14:51:09

标签: java reflection setter

我们可以使用属性名称找到setter方法名吗?

我有动态生成的map<propertyName,propertyValue>

通过使用map中的键(这是propertyName),我需要为object调用适当的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;
    }
}

我的地图包含两个项目:

map<"name","jack">
map<"company","inteld">

现在我正在迭代地图,当我从地图继续处理每个项目时,基于键(名称或公司)我需要调用适当的A类setter方法 例如对于第一项,我将名称作为键,因此需要调用新的A()。setName。

7 个答案:

答案 0 :(得分:17)

尽管使用反射可以做到这一点,但最好还是使用commons-beanutils。您可以轻松使用setSimpleProperty()方法,如下所示:

PropertyUtils.setSimpleProperty(a, entry.getKey(), entry.getValue());

假设a的类型为A

答案 1 :(得分:12)

如果您使用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属性编辑器,以便您可以为它不能处理的那些注册自定义类型转换器。)

答案 2 :(得分:5)

使用Map放置字段名称及其Setter方法名称,或使用字符串连接来设置&#34;设置&#34;使用First Letter大写的propertyName似乎是一种调用Setter方法的相当弱的方法。

您知道类名称并且可以迭代其属性并获取每个Property的Setter / GetterMethod名称的方案可以像下面的代码片段一样解决。

您可以从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();}

答案 3 :(得分:4)

Reflection API就是您所需要的。假设您知道属性名称,并且您有a类型的对象A

 String propertyName = "name";
 String methodName = "set" + StringUtils.capitalize(propertyName);
 a.getClass().getMethod(methodName, newObject.getClass()).invoke(a, newObject);

当然,你会被要求处理一些例外情况。

答案 4 :(得分:2)

你可以得到这样的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更高效,并允许您进行map-bean转换等等。

免责声明:我是开发Juffrou-reflect的人。如果您对如何使用它有任何疑问,我将非常乐意回复。

答案 5 :(得分:0)

这实际上是非常重要的,因为有关于camelCase字段名称大写的特殊规则。根据JavaBeans API(第8.8节),如果字段名称的前两个字符中的任何一个是大写字母,则该字段不是大写的。

因此

  • index变为Index - &gt; setIndex()
  • xIndex保持为xIndex - &gt; setxIndex()
  • URL保持为URL - &gt; 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;
}

然后可以通过预先设置&#34; set&#34;找到setter的名称。在它前面:"set" + capatalizeFieldName(field.getName())

这同样适用于getter,除了布尔类型使用&#34;是&#34;而不是&#34;得到&#34;作为前缀。

答案 6 :(得分:-1)

我认为你可以用反射来做到这一点,一个更简单的解决方案是在键上进行字符串比较并调用适当的方法:

 String key = entry.getKey();
 if ("name".equalsIgnoreCase(key))
   //key
 else
   // company
相关问题