浅拷贝和深拷贝

浅拷贝VS深拷贝
浅拷贝
demo
深拷贝
结果
浅拷贝和深拷贝的场景
优化拷贝
问题
其他方式
浅拷贝VS深拷贝
只复制指向某个对象的指针,不复制对象本身,新旧对象共享一个块内存

复制并创建一个一模一样的对象,不共享内存,修改新对象,旧对象保持不变

浅拷贝
demo

package com.jysemel.java.basic;

public class Demo {

private String name;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

package com.jysemel.java.basic;

public class Main {
public static void main(String[] args) {
Demo demo = new Demo();
demo.setName("jysemel");
demo.setAge(18);

System.out.println(demo.getName());

Demo demo1 = demo;
demo1.setName("jysemel1");

System.out.println(demo.getName());
System.out.println(demo1.getName());
}
}
深拷贝
实现 Cloneable 接口,并重写 clone 方法

package com.jysemel.java.basic;

import lombok.SneakyThrows;

import java.util.List;

public class Demo1 implements Cloneable{

private String name;
private int age;

private List list;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public List getList() {
return list;
}

public void setList(List list) {
this.list = list;
}

@SneakyThrows
@Override
public Demo1 clone() {
return (Demo1) super.clone();
}

@Override
public String toString() {
return "Demo1{" +
"name='" + name + ''' +
", age=" + age +
", list=" + list +
'}';
}
}

package com.jysemel.java.basic;

import java.util.ArrayList;
import java.util.List;

public class Main1 {
public static void main(String[] args) {
List list = new ArrayList<>();
Demo1 demo = new Demo1();
demo.setName("jysemel");
demo.setAge(18);
demo.setList(list);
demo.getList().add("2");

System.out.println(demo.getName());

Demo1 demo1 = demo.clone();
demo1.setAge(19);
demo1.setName("jysemel1");
demo.getList().add("4");

System.out.println(demo);
System.out.println(demo1);
}
}
结果

Demo1{name='jysemel', age=18, list=[2, 4]}
Demo1{name='jysemel1', age=19, list=[2, 4]}
String 对象一旦创建,内容不会变,修改会创建新对象,不会改变原来的对象

list 引用类型,没有进行深拷贝,修改会改变原来的对象

浅拷贝和深拷贝的场景

1、避免线程间共享可变状态导致线程安全问题,可传递该对象的深拷贝副本
2、DTO(数据传输对象)转换
3、缓存快照
优化拷贝
问题

1、对象嵌套层次越深,深拷贝的开销就越大
2、对于大量对象的复制操作,深拷贝可能导致性能下降
其他方式
其一 序列化 demo

package com.jysemel.java.basic.demo3;

import java.io.*;

public class Dept implements Serializable {

private static final long serialVersionUID = 1L;

private String name;
private String address;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "Dept{" +
"name='" + name + ''' +
", address='" + address + ''' +
'}';
}

public Dept(String name, String address) {
this.name = name;
this.address = address;
}

// 深拷贝方法:利用序列化
Dept deepCopy() {
try {
// 写入字节数组流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();

// 从字节数组流读取
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (Dept) ois.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

package com.jysemel.java.basic.demo3;

public class SimpleDeepCopyDemo {

public static void main(String[] args) {

Dept p1 = new Dept("张三", "333");

// 深拷贝
Dept p2 = p1.deepCopy();

// 打印原始和副本
System.out.println("原始: " + p1);
System.out.println("副本: " + p2);

// 修改副本的基本类型字段
p2.setName("李四");
p2.setAddress("李四33");

// 再次打印,观察原始对象是否被影响
System.out.println("\n修改副本后:");
System.out.println("原始: " + p1); // 原始对象不受影响
System.out.println("副本: " + p2);
}
}

posted @ 2026-02-12 16:38  砍材农夫  阅读(9)  评论(0)    收藏  举报