Java使用备忘录模式恢复Vector对象失效问题求解
问题原因
核心问题是引用类型的浅拷贝问题:
- int属于基本数据类型,赋值时是直接复制值本身,每个备忘录存储的是状态生成那一刻的独立数值,后续原变量的修改不会影响备忘录里存储的旧值,所以int场景下撤销功能可以正常运行。
- Vector属于引用类型,你现有代码中
Memento构造方法里的mState=mc.state是直接把原对象state的内存地址赋值给备忘录的mState,二者指向同一个Vector实例。后续你对原state做add操作时,所有备忘录里存储的mState都会同步变化,所有快照实际都指向最新的Vector状态,自然撤销后不会回退到历史版本。
修复方案
只需要修改Memento类的构造方法,存储状态时创建Vector的独立副本即可:
public Memento(MyClass mc) { this.myclass = mc; // 调用Vector的拷贝构造方法,生成独立的副本存储 this.mState = new Vector(mc.state); }
同时建议优化Caretaker的undo方法,避免空指针异常和重复调用lastElement()的潜在问题:
public void undo(){ // 先判断快照列表是否为空 if (undoList.isEmpty()) { return; } // 直接移除最后一个快照并恢复 Memento lastMemento = undoList.remove(undoList.size() - 1); lastMemento.restore(); }
内容的提问来源于stack exchange,提问作者AngusC
相关产品推荐
相关产品推荐

