8

javascriptでは、これを行うことができます:

function MyObject(obj) {
    for (var property in obj) {
        this[property] = obj[property];
    }
}

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]?
    }
}
4

4 に答える 4

7

Joelの答えに同意できないわけではありませんが、基本的に最善の努力が必要な場合は、それほど難しいことではないと思います。基本的に、そこにあるかどうか、そして設定しようとしているかどうかを確認します。それがうまくいかない場合は、まあ、私たちは試しました。例えば:

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class MyObject {

    protected String lorem;
    protected String ipsum;
    protected int integer;


    public MyObject(Map<String, Object> valueMap){
        for (String key : valueMap.keySet()){
            setField(key, valueMap.get(key));
        }
    }

    private void setField(String fieldName, Object value) {
        Field field;
        try {
            field = getClass().getDeclaredField(fieldName);
            field.set(this, value);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Map<String, Object> valueMap = new HashMap<String, Object>();
        valueMap.put("lorem", "lorem Value");
        valueMap.put("ipsum", "ipsum Value");
        valueMap.put("integer", 100);
        valueMap.put("notThere", "Nope");

        MyObject f = new MyObject(valueMap);
        System.out.println("lorem => '"+f.lorem+"'");
        System.out.println("ipsum => '"+f.ipsum+"'");
        System.out.println("integer => '"+f.integer+"'");
    }
}
于 2012-10-29T19:59:33.980 に答える
4

まず、可能であればマップを使用します。

class MyObject {

     // String myProperty; // ! not this
     HashMap<String,String> myProperties;  // use this instead

}

ただし、フィールドを動的に設定したいとします。

public MyObject(HashMap<String, String> props) {
    for (Map.Entry<String,String> entry : props.entrySet()) {
        Field field = this.getClass().getField(entry.getKey());
        field.set(this, entry.getValue());
    }
}

もちろん、上記のコンストラクターでtry/catchを使用することをお勧めします。

于 2019-02-22T04:47:43.330 に答える
3

はい、あなたは次の線に沿って何かを振り返ることによってそれを行うことができます:

/**
 * 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);
        }
    }
}

ただし、Javaにあまり詳しくない場合は、このアプローチは危険でエラーが発生しやすいため、可能な限り避ける必要があります。たとえば、Field設定しようとしている文字列が実際に文字列を期待しているという保証はありません。そうでない場合は、プログラムがクラッシュして書き込みます。

于 2012-10-29T19:36:32.623 に答える
1

さて、本当にリフレクションを下げたいのであれば、Introspectorクラスを見て、BeanInfoからPropertyDescriptorsのリストを取得することをお勧めします。

于 2012-10-29T20:11:49.580 に答える