字段分配存储供以后完成

问题描述

| 我有两节课。第一类具有
someField
,第二类需要更改,因此第一类称为
FirstClass.setSomeField(value)
。第二类当时无法更改该字段,因此它将此“ 2”存储到列表中,稍后将通过该列表并应用必要的更改。该类必须以一种可以比较
FutureChange
实例的方式来存储它,即避免两次将同一字段设置两次。 实现“ 2”的最佳方法是什么?通过反射,这很容易。问题是我将有数百个类,每个类都有许多字段。 我什至尝试了一个地图,其中有一个字段名开关:
public class Example { 

    public static Integer number;
    public static String words;

    public static void main(String args[]) {
        Map<Field,Object> map = new HashMap<Field,Object>();
            // store modifications
        map.put(Field.number,new Integer(10));
        map.put(Field.words,\"Words\");
        // some time later
        for(Map.Entry<Field,Object> entry: map.entrySet()) {
            modify(entry.getKey(),entry.getValue());
        }
    }

    public static void modify(Field m,Object value) {
        switch(m){
        case number:
            number = (Integer) value;
            break;
        case words:
            words = (String) value;
            break;
        }
    }

    public enum Field {
        number,words;
    }
}
但这不是最有效的方法,并且随着班级的扩大而被堵塞。有谁知道如何最好地实现这一目标? 一些代码
public class Main {
    FirstClass a = new FirstClass();
    SecondClass b = new SecondClass();
    // Third,Fourth,etc.

    public static void main(String args[]) {
        while(true) {
            // run each,no modifications allowed
            a.run(); // may want to modify several variables of b
            b.run(); // same as above
            // end of all runs,Now modify
            a.modifyAll();
            b.modifyAll();
        }
    }
}
如您所见,我必须在运行期间将其存储,然后再执行。 存储匿名内部
Callable
并稍后再调用会很完美,但是我需要检查它在做什么,以便我可以比较两者并确定它们是否冲突。     

解决方法

        我会按照您的建议使用反射。这将比直接应用更改慢得多。如果您真的想提高效率,最好将代码分为两个阶段/阶段,一个阶段使用当前值,另一个阶段应用更改,而不是尝试存储更改。
public class StoredChanges {
    private final Map<Object,Map<String,Object>> changes = new IdentityHashMap<Object,Object>>();

    public void storeChange(Object o,String fieldName,Object value) {
        Map<String,Object> changedForObject = changes.get(o);
        if (changedForObject == null)
            changes.put(o,changedForObject = new LinkedHashMap<String,Object>());
        changedForObject.put(fieldName,value);
    }

    public void applyChanges() {
        for (Map.Entry<Object,Object>> objectMapEntry : changes.entrySet()) {
            Object o = objectMapEntry.getKey();
            for (Map.Entry<String,Object> fieldChange : objectMapEntry.getValue().entrySet()) {
                String fieldName = fieldChange.getKey();
                try {
                    Method setter = o.getClass().getMethod(\"set\" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));
                    setter.invoke(o,fieldChange.getValue());
                } catch (Exception e) {
                    e.printStackTrace(); // or log it.
                }
            }
        }
        changes.clear();
    }
}