结论:
- 都生成新对象
- 浅拷贝:基本类型重新生成一份,"引用类型"引用旧地址,需要实现 Cloneable 接口
- 深拷贝:基本类型重新生成一份,"引用类型"也重新生成,需要实现 Serializable 接口
1.浅拷贝:
- 浅拷贝实现 Cloneable 接口
@Data
public class Person implements Cloneable {
private String name;
private Integer age;
private Inner inner;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Person{" + hashCode() +
" name='" + name + '\'' +
", age=" + age +
", inner=" + inner +
'}';
}
/**
* 内部类
*/
@Data
static class Inner implements Serializable{
private String name;
@Override
public String toString() {
return "Inner{" + hashCode()+
" name='" + name + '\'' +
'}';
}
}
}
- 测试
public class ShallowCopyDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
person.setName("abc");
person.setAge(18);
person.setInner(new Person.Inner());
person.getInner().setName("abc");
Person shallowCopyPeron = (Person) person.clone();
shallowCopyPeron .setName("def");
shallowCopyPeron .getInner().setName("def");
System.out.println(person);
System.out.println(shallowCopyPeron );
}
}
- 结果
Person{6052315 name='abc', age=18, inner=Inner{99392 name='def'}}
Person{6228076 name='def', age=18, inner=Inner{99392 name='def'}}
可以看出来,Person 浅拷贝生成了新对象,因为 hashCode 值不一样;但两者 Inner 属性的 hashCode 一样,说明引用类型只是复制了引用地址
2.深拷贝:
- 深拷贝实现 Serializable 接口
@Data
public class Person implements Serializable {
private String name;
private Integer age;
private Inner inner;
public Person deepClone(){
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(bos);
objectOutputStream.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(bis);
Person person = (Person) objectInputStream.readObject();
return person;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
@Override
public String toString() {
return "Person{" + hashCode() +
" name='" + name + '\'' +
", age=" + age +
", inner=" + inner +
'}';
}
/**
* 内部类
*/
@Data
static class Inner implements Serializable{
private String name;
@Override
public String toString() {
return "Inner{" + hashCode()+
" name='" + name + '\'' +
'}';
}
}
}
- 测试
public class DeepCopyDemo {
public static void main(String[] args) {
Person person = new Person();
person.setName("abc");
person.setAge(18);
person.setInner(new Person.Inner());
person.getInner().setName("abc");
Person deepClonePeron = person.deepClone();
deepClonePeron.setName("def");
deepClonePeron.getInner().setName("def");
System.out.println(person);
System.out.println(deepClonePeron);
}
}
- 结果
Person{6049336 name='abc', age=18, inner=Inner{96413 name='abc'}}
Person{6228076 name='def', age=18, inner=Inner{99392 name='def'}}
可以看出来,Person 深拷贝生成了新对象,因为 hashCode 值不一样;同样两者 Inner 属性的 hashCode 也不一样,引用类型也生成了新对象
参考:Java 浅拷贝和深拷贝