首页 归档 关于 learn love 工具

java深拷贝

Java 实现对象深拷贝的方式有两种

  1. 序列化
  2. 实现类的clone方法
    下文介绍通过序列化实现通用对象深拷贝

引入依赖

需要依赖外部工具包 Apache Commons Lang

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

范例

  1. 类对象,都需要实现Serializable
public class Account implements Serializable {
    private static final long serialVersionUID = 1L;

    private List<Email> emails;

    public void setEmails(List<Email> emails) {
        this.emails = emails;
    }

    public List<Email> getEmails() {
        return emails;
    }
}


public class Email implements Serializable {
    private static final long serialVersionUID = 1L;

    private String email;

    public Email() {
    }

    public Email(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return email;
    }

    // generated by Eclipse
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((email == null) ? 0 : email.hashCode());
        return result;
    }

    // generated by Eclipse
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Email other = (Email) obj;
        if (email == null) {
            if (other.email != null)
                return false;
        } else if (!email.equals(other.email))
            return false;
        return true;
    }
} 

  1. 测试用例
    @Test
    public void copy() {
         // 构建复杂对象1
        Account accountForm = new Account(); 
        List<Email> emailsSrc = new ArrayList<Email>(); 
        emailsSrc.add(new Email("a@example.com"));
        emailsSrc.add(new Email("b@example.com"));
        emailsSrc.add(new Email("c@example.com")); 
        accountForm.setEmails(emailsSrc);
        // 深复制出新对象2
        Account account = SerializationUtils.clone(accountForm);
        // 修改原来的对象1属性值
        emailsSrc.get(0).setEmail("toomi");

        // 后面能比对,原始对象1的属性被修改
        assert(accountForm.getEmails().get(0).getEmail().equals("toomi"));
        // 复制出来的对象2属性没有修改,复制不是内存地址引用,前后对象是独立的
        assert(account.getEmails().get(0).getEmail().equals("a@example.com"));
    }