使用reflection调用类中的所有setter
我有一个域对象,为了这个问题的目的,我将使用以下私有变量调用Person:
String name int age
每个人都有吸气剂和二传手。 现在我还有一个Map
其中包含以下条目:
name, phil age, 35
我想在Person类中填充所有setter方法的列表,然后循环遍历此列表并使用map中的值调用每个方法。
这是否可能,因为我在网上看不到任何接近这个的例子。 非常感谢例子。
当然有可能! 您可以通过执行以下操作获得以“set”开头的所有方法:
Class curClass = myclass.class; Method[] allMethods = curClass.getMethods(); List setters = new ArrayList (); for(Method method : allMethods) { if(method.getName().startsWith("set")) { setters.add(method); } }
现在你已经掌握了这些方法。 你是否已经知道如何为你的class级实例打电话?
你从Apache Commons BeanUtils尝试过BeanUtils.populate()
)吗?
BeanUtils.populate(yourObject, propertiesMap);
我想你可以使用一个库, Apache Commons BeanUtils 。 如果您有一个包含字段和值对的映射,则PropertyUtils类可以帮助您:
Person person = new Person(); for(Map.Entry entry : map.entrySet()) PropertyUtils.setProperty(person, entry.getKey(), entry.getValue());
这是一个完整的解决方案,可以预先validation输出类,从而为地图包含的所有属性调用setter。 它纯粹使用java.beans
和java.lang.reflect
。
public Object mapToObject(Map input, Class> outputType) { Object outputObject = null; List 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 getPropertyDescriptors(Class> outputType) { List 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; } }