首页 > 解决方案 > 如何避免对象的相同引用

问题描述

我有这个问题,我正在创建一个 Junit 测试,我想先用 setUp 方法做点什么。查看我的示例代码:

class ClassDaoImplTests {

    @Autowired
    private NamedParameterJdbcTemplate template;

    private Project modifiedProject;
    
    private Project origProject;
    
    List<Project> projList;

    @BeforeAll
    protected void setUp() {
        
        preserveOriginalProjectData();
        prepareProjectDataToUpdate();
    }

    public void preserveOriginalProjectData() {
        
        projList = getSortedProjectList();
        origProject = projList.get(0);
    }
    
    public void prepareProjectDataToUpdate() {
        
        modifiedProject = projList.get(0);
        modifiedProject.setProjName(modifiedProject.getProjName() + "_Edit");
    }

    public List<Project> getSortedProjectList() {

        String sql = "SELECT * FROM Table1 ORDER BY id ASC";
        return template.query(sql, new BeanPropertyRowMapper<Project>(Project.class));
    }

}

无论我对 做什么modifiedProject,它都会反映在origProjectobject 以及列表中的 object 上。即使我使用这种方法,结果也是一样的:

 protected void setUp() {
    
    projList = getSortedProjectList();
    origProject = projList.get(0);
    prepareProjectDataToUpdate();
} 

如何保留原始对象的数据?我没有包含其他代码来最小化代码的大小。但只是陈述逻辑。实际上我希望origProject数据用于tearDown()恢复表中的值。

标签: javaspring-bootjunitjava-8spring-jdbc

解决方案


回复:无论我对 modifiedProject 做什么,它都会反映在 origProject 对象以及列表中的对象上。

这里只有一个对象。复制引用不会复制引用的对象。

在这之后:

  modifiedProject = projList.get(0);

然后“modifiedProject”指向作为“projList”第一个元素的对象,而不是它的副本。当然,'origProject' 指向同一个对象。

如果您想要一个 Project 的副本,那么 Project 类需要提供一种制作副本的方法。


在您的特定情况下,您可以通过再次执行 SELECT 来回避它,从而产生一个单独的实例。我不完全确定这一点,不熟悉您使用的数据库类,但似乎它从一个 SQL 语句到下一个 SQL 语句都没有保留任何内容。当然,这会带来“排序列表中的第一个元素”可能与以前不同的风险,所以我不建议这样做。


推荐阅读