Java对象重写clone方法实现深拷贝
在Java语言里,当我们需要拷贝一个对象时,有两种类型的拷贝:浅拷贝与深拷贝。浅拷贝只是拷贝了源对象的地址,所以源对象的值发生变化时,拷贝对象的值也会发生变化。而深拷贝则是拷贝了源对象的所有值,所以即使源对象的值发生变化时,拷贝对象的值也不会改变。
实现深拷贝的方法有很多,今天主要使用重写clone方法进行深拷贝
- 首先实体类需要实现Cloneable接口
- 重写clone方法,将protected改为public,将返回类型改为当前实体类的类型
- 如果实体类中的属性不全是基础数据类型和String,那么对该属性类也要进行同样的操作让它支持深拷贝
- 实现如下:
@Data @AllArgsConstructor @NoArgsConstructor public class User implements Cloneable{ private String name; private Address address; /** * 因为Address不是基础数据类型或者String类型 * 所以需要先重写Address类的clone方法才能完成深拷贝 * 并且重写clone方法时可以将protected改为public 将返回类型改为重写的类 */ @Override public User clone() throws CloneNotSupportedException { User obj = (User) super.clone(); obj.setAddress(this.address.clone()); return obj; } } @Data @AllArgsConstructor @NoArgsConstructor public class Address implements Cloneable{ private String addr; @Override public Address clone() throws CloneNotSupportedException { return (Address) super.clone(); } } public class Main { public static void main(String[] args) throws CloneNotSupportedException { Address address = new Address("China"); User user01 = new User("name", address); User user02 = user01.clone(); System.out.println("u1 -> " + user01); // User(name=name, address=Address(addr=China)) System.out.println("u2 -> " + user02); // User(name=name, address=Address(addr=China)) address.setAddr("US"); System.out.println("u1 -> " + user01); // User(name=name, address=Address(addr=US)) System.out.println("u2 -> " + user02); // User(name=name, address=Address(addr=China)) } }