Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 字段分配存储以供以后完成_Java_Class Design - Fatal编程技术网

Java 字段分配存储以供以后完成

Java 字段分配存储以供以后完成,java,class-design,Java,Class Design,我有两节课。第一个类有一些第二个类需要更改的字段,因此第一个类调用FirstClass.setSomeFieldvalue。第二个类此时无法更改字段,因此它将这个未来的更改存储到一个列表中,稍后它将遍历该列表并应用必要的更改。类必须以能够比较FutureChange实例的方式存储它,即避免两次设置同一字段,以及其他事情 实施未来变革的最佳方式是什么?有了反射,这很容易。问题是我将有数百个类,每个类都有许多字段 我甚至尝试了一个带有字段名开关的地图: public class Example {

我有两节课。第一个类有一些第二个类需要更改的字段,因此第一个类调用FirstClass.setSomeFieldvalue。第二个类此时无法更改字段,因此它将这个未来的更改存储到一个列表中,稍后它将遍历该列表并应用必要的更改。类必须以能够比较FutureChange实例的方式存储它,即避免两次设置同一字段,以及其他事情

实施未来变革的最佳方式是什么?有了反射,这很容易。问题是我将有数百个类,每个类都有许多字段

我甚至尝试了一个带有字段名开关的地图:

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 StoredChanges {
    private final Map<Object, Map<String, Object>> changes = new IdentityHashMap<Object, Map<String, 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, Map<String, 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();
    }
}

你考虑过线程吗?也许您可以在调用FirstClass.setSomeFieldvalue之前阻止正在执行的线程。然后,另一个线程将其解锁,以允许执行更改。看看java.util.concurrent包。未来任务、可调用项、障碍等。您可能需要一些有用的东西。
public class StoredChanges {
    private final Map<Object, Map<String, Object>> changes = new IdentityHashMap<Object, Map<String, 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, Map<String, 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();
    }
}