情况:我有由不同实例表示的同一对象的多个状态(使用深拷贝制作)。现在我想确保,无论访问这些分组实例中的哪一个,执行修改的所有操作都被重定向到这些实例中最年轻的实例[1]。
示例:[2]
//Let's create an object
MyObject mObj = new MyObject(...);
//Let's create a list of past states
List<MyObject> pastStates = new ArrayList<MyObject>();
//doing some operations on mObj ....
mObj.modify(...);
//done modifying mObj, now let's save it's state and then create a copy to begin again
pastStates.add(mObj.copy());
//more of this...
mObj.modify(...);
pastStates.add(mObj.copy());
//let's compare some old states for whatever reason (e.g. part of an algorithm)
compare(MyObject o1, MyObject o2) {
if(o1.getA() == o2.getA()) {
o2.modify(...); //wait, we modified an old state...
}
现在这是一个相当明显的例子,并且可能是 程序员错误的经典案例。他们修改了一些明显被宣传为过去状态的东西......但是说我们仍然想变得友善并尝试提供帮助因此拦截方法调用并在正确的实例上执行它即最年轻/主实例。[3]
问题: 有没有办法用标准 java 来做到这一点? 奖励: 有没有一种方法不会对性能产生可怕的影响?
背景:我正在尝试用不同的方法来制作库/引擎,我写作是为了好玩,更不容易被最终用户滥用。因为无论如何我都会在内部需要这些状态(某些后台功能的及时快照),我想让最终用户也可以使用它们,这样他们就可以从我的状态保持中获益,例如用于分析算法。
[1] 一个对象可以有多个互不相关的实例组;关系可能会通过指向最年轻实例的单向链接来保持,该实例永远不会改变。
[2] 此代码仅作为示例,显然最终用户在编写代码时多加注意可以避免此错误。
[3] 现在防止修改的一种简单方法是将对象包装到一个不可变版本中,该版本在尝试修改它时会抛出异常 > 但我们不要自己编写这个对象,也不想强制最终用户编写他们自己的对象的两个版本,如果我们不必...
最佳答案
我可能会创建两个类:一个是不可变的“内部”类,另一个是维护内部列表的“外部”类。 (注意:我不是指 JLS 意义上的内部类,只是一个完全由其包装器控制的对象。)
像这样:
public final class Outer {
private final List<Inner> history = new ArrayList<>(); //history is inverted for brevity, 0 is the latest one
public Outer(int x) {
this.history.add(new Inner(x));
}
public void add(int x) {
history.add( 0, new Inner(history.get(0).x+x);
}
public Inner current() {
return history.get(0);
}
public static final class Inner {
private final int x;
private Inner(int x) {
this.x = x;
}
public int getX() {
return x;
}
}
}
使用此设置,客户端只能实例化 Outer
,只能改变 Outer
,但可以访问所有过去状态的只读副本。没有办法不小心修改过去的状态。也不需要单独的分组逻辑,因为 Outer
的每个实例自然只记录自己的历史。
关于java - 是否可以在运行时将方法调用重定向到同一对象的另一个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33842614/