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))
}
}