如何使用属性名称来标识setter方法?(How to identify setter method

2019-07-20 15:23发布

我们可以使用属性名称查找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?