在Java中复制对象存储旧值是否为最优实现方案?
处理Java编辑页面中对象旧值的保存与传递
嘿,你的思路方向是对的——用拷贝构造函数来复制对象以保留旧值,这样后续调用存储过程时就能准确传递原始状态了。我来给你补充一些关键细节和优化建议,确保整个流程不出问题:
1. 确保拷贝构造函数是深拷贝
这是最核心的一点!如果你的Education类里包含引用类型的属性(比如List、自定义对象等),浅拷贝会导致edOld和edNew共享同一个引用,用户修改edNew时会意外改动edOld的属性值,完全失去保留旧值的意义。
举个正确的深拷贝构造函数示例:
public class Education { private String degree; private Date graduationDate; private List<Course> relatedCourses; // 引用类型属性 // 深拷贝构造函数 public Education(Education other) { // 基本类型/不可变类型(注意Date是可变的,需拷贝新实例) this.degree = other.degree; this.graduationDate = other.graduationDate != null ? new Date(other.graduationDate.getTime()) : null; // 对集合类型进行深拷贝 if (other.relatedCourses != null) { // 如果Course也是自定义对象,要进一步拷贝每个Course实例 this.relatedCourses = other.relatedCourses.stream() .map(Course::new) // 假设Course也有拷贝构造函数 .collect(Collectors.toList()); } else { this.relatedCourses = null; } } // 其他属性的getter、setter等 }
2. 安全存储旧值,避免意外修改
拿到edOld之后,要确保它在整个编辑流程中不会被误修改。根据你的Web场景,可以选择:
- 存在HttpSession中:适合跨请求保存旧值,直到提交编辑时取出
- 放在页面的隐藏域:如果是表单提交,可以把旧值的关键属性序列化后存在隐藏域(注意敏感数据不要这么做)
- 作为后台请求参数/Model属性传递:适合单次请求跳转的场景
示例代码(基于HttpSession的场景):
public void onClickEdit(Education e) { Education edOld = new Education(e); // 深拷贝得到旧值 Education edNew = new Education(e); // 供用户编辑的新对象 // 把旧值存入会话,后续提交时取出 request.getSession().setAttribute("eduOldValue", edOld); goToPage(a); // 跳转到编辑页面,将edNew传递给页面供用户修改 } // 编辑提交时的处理方法 public void onSubmitEducation(Education editedEdNew) { // 从会话中取出旧值 Education edOld = (Education) request.getSession().getAttribute("eduOldValue"); // 调用存储过程,传递旧值和修改后的新值 yourStoredProcedureExecutor.saveChanges(edOld, editedEdNew); // 清理会话中的旧值,避免内存泄漏 request.getSession().removeAttribute("eduOldValue"); }
3. 额外优化建议
- 工具类简化拷贝:如果
Education属性很多,手写拷贝构造函数太繁琐,可以用ModelMapper或Apache Commons BeanUtils来实现深拷贝,但要提前测试工具的拷贝行为,避免浅拷贝的坑。 - 校验修改状态:在提交时可以对比
edOld和editedEdNew的属性,只有当确实有修改时才调用存储过程,提升系统性能。 - 不可变旧值:可以把
edOld的属性设置为只读(去掉setter,或者用final修饰),从根源上避免被误修改。
内容的提问来源于stack exchange,提问作者pans
相关产品推荐
相关产品推荐

