1.浅拷贝
创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
1.1 浅拷贝的实现
1.1.1 实现Clone接口
Object父类有个clone()的拷贝方法,不过它是protected类型的,我们需要重写它并修改为public类型。除此之外,子类还需要实现Cloneable接口来告诉JVM这个类是可以拷贝的
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* Description:
*
* @author jack
* @date 2021/8/4 3:42 下午
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable, Cloneable {
private static final long serialVersionUID = -1286423671768591169L;
private String name;
private Integer age;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* Description:
*
* @author jack
* @date 2021/8/4 3:42 下午
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Address implements Serializable , Cloneable {
private static final long serialVersionUID = -2220826382327087863L;
private String country;
private String city;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试
/**
* Description:
*
* @author jack
* @date 2021/8/4 3:44 下午
*/
public class CloneTest2 {
public static void main(String[] args) throws CloneNotSupportedException {
User user1 = User.builder()
.name("张三")
.age(18)
.address(Address.builder()
.country("中国")
.city("上海")
.build())
.build();
User user2 = (User) user1.clone();
System.out.println(user1 == user2); // false
System.out.println(user1.getAddress() == user2.getAddress()); // true
}
}
1.1.2 使用BeanUtils.copyProperties
import org.springframework.beans.BeanUtils;
/**
* Description:
*
* @author jack
* @date 2021/8/4 3:44 下午
*/
public class CloneTest2 {
public static void main(String[] args) throws CloneNotSupportedException {
User user1 = User.builder()
.name("张三")
.age(18)
.address(Address.builder()
.country("中国")
.city("上海")
.build())
.build();
User user2 = new User();
BeanUtils.copyProperties(user1, user2);
System.out.println(user1 == user2); // false
System.out.println(user1.getAddress() == user2.getAddress()); // true
}
}
2.深拷贝
创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
2.1 深拷贝的实现方式
2.1.1 使用SerializationUtils.clone
需要依赖commons-lang3
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
SerializationUtils.clone需要类实现Serializable接口
import org.apache.commons.lang3.SerializationUtils;
/**
* Description:
*
* @author jack
* @date 2021/8/4 3:44 下午
*/
public class CloneTest {
public static void main(String[] args) {
User user1 = User.builder()
.name("张三")
.age(18)
.address(Address.builder()
.country("中国")
.city("上海")
.build())
.build();
User user2 = SerializationUtils.clone(user1);
System.out.println(user1 == user2); // false
System.out.println(user1.getAddress() == user2.getAddress()); //false
}
}