3

我有一个域对象,出于这个问题的目的,我将使用以下私有变量调用 Person:

String name
int age

它们中的每一个都有getter 和setter。现在我也有Map<String, String>以下条目:

name, phil
age, 35

我想在 Person 类中填充所有 setter 方法的列表,然后遍历该列表并使用映射中的值调用每个方法。

这是否可能,因为我在网上看不到任何接近此的示例。非常感谢示例。

4

4 回答 4

14

当然有可能!您可以通过执行以下操作获取所有以“set”开头的方法:

Class curClass = myclass.class;
Method[] allMethods = curClass.getMethods();
List<Method> setters = new ArrayList<Method>();
for(Method method : allMethods) {
    if(method.getName().startsWith("set")) {
        setters.add(method);
    }
}

现在你已经掌握了方法。您是否已经知道如何为您的类实例调用它们?

于 2012-05-08T21:46:07.983 回答
2

您是否尝试过BeanUtils.populate())来自Apache Commons BeanUtils

BeanUtils.populate(yourObject, propertiesMap);
于 2012-05-08T21:50:14.023 回答
0

我认为您可以使用一个库,即Apache Commons BeanUtils。如果您有一个包含字段和值对的映射,PropertyUtils类可以帮助您:

Person person = new Person();
for(Map.Entry<String, Object> entry : map.entrySet())
    PropertyUtils.setProperty(person, entry.getKey(), entry.getValue());
于 2012-05-08T21:49:16.497 回答
0

这是一个完整的解决方案,可以预先验证输出类,然后为地图包含的所有属性调用设置器。它纯粹使用java.beansjava.lang.reflect

public Object mapToObject(Map<String, Object> input, Class<?> outputType) {
    Object outputObject = null;
    List<PropertyDescriptor> outputPropertyDescriptors = null;
    // Test if class is instantiable with default constructor
    if(isInstantiable(outputType) 
            && hasDefaultConstructor(outputType)
            && (outputPropertyDescriptors = getPropertyDescriptors(outputType)) != null) {
        try {
            outputObject = outputType.getConstructor().newInstance();
            for(PropertyDescriptor pd : outputPropertyDescriptors) {
                Object value = input.get(pd.getName());
                if(value != null) {
                    pd.getWriteMethod().invoke(outputObject, value);
                }
            }
        } catch (InstantiationException|IllegalAccessException|InvocationTargetException|NoSuchMethodException e) {
            throw new IllegalStateException("Failed to instantiate verified class " + outputType, e);
        }
    } else {
        throw new IllegalArgumentException("Specified outputType class " + outputType + "cannot be instantiated with default constructor!");
    }
    return outputObject;
}

private List<PropertyDescriptor> getPropertyDescriptors(Class<?> outputType) {
    List<PropertyDescriptor> propertyDescriptors = null;
    try {
        propertyDescriptors = Arrays.asList(Introspector.getBeanInfo(outputType, Object.class).getPropertyDescriptors());
    } catch (IntrospectionException e) {
    }
    return propertyDescriptors;
}

private boolean isInstantiable(Class<?> clazz) {
    return ! clazz.isInterface() && ! Modifier.isAbstract(clazz.getModifiers());
}

private boolean hasDefaultConstructor(Class<?> clazz) {
    try {
        clazz.getConstructor();
        return true;
    } catch (NoSuchMethodException e) {
        return false;
    }
}
于 2017-03-07T13:32:40.120 回答