In javascript, I can do this:
function MyObject(obj) { for (var property in obj) { this[property] = obj[property]; } }
Can I do anything close in Java?
class MyObject { String myProperty; public MyObject(HashMap<String, String> props) { // for each key in props where the key is also the name of // a property in MyObject, can I assign the value to this.[key]? } }
Advertisement
Answer
Yes, you can do it by reflection with something along the following lines:
/** * Returns a list of all Fields in this object, including inherited fields. */ private List<Field> getFields() { List<Field> list = new ArrayList<Field>(); getFields(list, getClass()); return list; } /** * Adds the fields of the provided class to the List of Fields. * Recursively adds Fields also from super classes. */ private List<Field> getFields(List<Field> list, Class<?> startClass) { for (Field field : startClass.getDeclaredFields()) { list.add(field); } Class<?> superClass = startClass.getSuperclass(); if(!superClass.equals(Object.class)) { getFields(list, superClass); } } public void setParameters(Map<String, String> props) throws IllegalArgumentException, IllegalAccessException { for(Field field : getFields()) { if (props.containsKey(field.getName())) { boolean prevAccessible = field.isAccessible(); if (!prevAccessible) { /* * You're not allowed to modify this field. * So first, you modify it to make it modifiable. */ field.setAccessible(true); } field.set(this, props.get(field.getName())); /* Restore the mess you made */ field.setAccessible(prevAccessible); } } }
However, if you are not very familiar with Java, this approach should be avoided if at all possible, as it is somewhat dangerous and error prone. For instance, there is no guarantee that the Field
you are attempting to set are actually expecting a String. If it is the case that they are not, your program will crash and burn.