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