Java对象深复制与浅复制实例详解

发布时间 - 2026-01-11 01:20:31    点击率:

 Java对象深复制与浅复制实例详解

我们在遇到一些业务场景的时候经常需要对对象进行复制,对于对象的复制一般有两种方式,深复制和浅复制

浅复制:对象的复制仅是对象本身,对象引用的其它对方并不会复制。

深复制:对象的复制包含对象引用的对象。

Java所有对象的基类提供了clone方法,但是这个方法是protected native修饰,因此只暴露给之类去重写,外部是无法直接调用的。

我们现在来测试两种复制,首选是浅复制,浅复制要实现Cloneable接口。

// 课程对象
class Class {
  private String name;

  public String getName() {
    return name;
  }

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

}
// 学生对象
class User implements Cloneable {
  private String name;
  private Long id;
  // 课程引用
  private Class c;

  public Class getC() {
    return c;
  }

  public void setC(Class c) {
    this.c = c;
  }

  public String getName() {
    return name;
  }

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

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  @Override
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }

  @Override
  public int hashCode() {
    return super.hashCode();
  }

  @Override
  public boolean equals(Object obj) {

    if (obj instanceof User) {
      User user = (User) obj;
      if (this.id == user.getId() && this.getName() == user.getName()) {
        return true;
      }
      if (user.getId().equals(this.id)
          && user.getName().equals(this.name)) {
        return true;
      }
      return false;
    } else
      return false;
  }

}

我们来测试:

 User user1 = new User();
    User user2 = user1;

    User user3 = (User) user1.clone();

    System.out.println(user1 == user2);
    System.out.println(user3 == user1);
    System.out.println(user3.equals(user1));
    System.out.println(user3.getName() == user3.getName());// true,浅复制

    Class c = new Class();
    c.setName("语文");
    user1.setC(c);
    // 测试复制深度
    User user4 = (User) user1.clone();
    System.out.println(user4.getC() == user1.getC()); // true,说明引用的对象依然是同一个对象

对象的复制并没复制引用所指向的对象class,复制出来的引用指向的同一个地址。

深复制采用序列化与反序列的方式去获取,也有种说法类似于腌菜,用流的方式腌制进去又取出来,实现深度复制。

class Car implements Serializable {
  /**
   * 
   */
  private static final long serialVersionUID = 42342L;
  private String name;

  public String getName() {
    return name;
  }

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

}

// 深复制
class People implements Serializable{
  /**
   * 
   */
  private static final long serialVersionUID = 543535212412L;
  private Car car;

  public Car getCar() {
    return car;
  }

  public void setCar(Car car) {
    this.car = car;
  }

  public People deepClone() throws IOException, ClassNotFoundException {
    // 腌制
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(out);
    oos.writeObject(this);
    // 取出
    ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(input);
    return (People) ois.readObject();
  }

}

测试深复制:

// 深复制
    Car car = new Car();
    car.setName("benz");
    People p = new People();
    p.setCar(car);

    try {
      People p2 = p.deepClone();
      System.out.println(p2.getCar() == p.getCar()); // false,说明引用的对象也进行了复制
    } catch (ClassNotFoundException | IOException e) {
      e.printStackTrace();
    }

例外提及一下生成对象的五种办法:

1.new
2.Class类的newInstance
3.Constructor类newInstance
4.Clone方式
5.反序列化的方式

其中2与3即是反射的方式。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Java对象深复制与浅复制  # java  # 对象复制  # 利用Java反射机制实现对象相同字段的复制操作  # Java对象的复制三种方式(小结)  # Java编程实现对象克隆(复制)代码详解  # Java中对象的深复制(深克隆)和浅复制(浅克隆)介绍  # 深入java对象复制的分析  # Java基础之面向对象机制(多态、继承)底层实现  # Java MapStruct解了对象映射的毒  # 详解Java对象的内存布局  # Java基础详解之面向对象的那些事儿  # 深入理解Java对象复制  # 两种  # 希望能  # 仅是  # 重写  # 我们现在  # 即是  # 有两种  # 谢谢大家  # 类似于  # 五种  # 进行了  # 化与  # 直接调用  # 序列化  # Override  # Object  # getId  # implements  # setC  # getC 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 高防服务器租用指南:配置选择与快速部署攻略  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  Laravel如何生成和使用数据填充?(Seeder和Factory示例)  简历没回改:利用AI润色让你的文字更专业  高端建站如何打造兼具美学与转化的品牌官网?  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  iOS正则表达式验证手机号、邮箱、身份证号等  Laravel如何使用withoutEvents方法临时禁用模型事件  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  Laravel安装步骤详细教程_Laravel环境搭建指南  Laravel中的withCount方法怎么高效统计关联模型数量  如何正确选择百度移动适配建站域名?  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  Python3.6正式版新特性预览  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  黑客如何通过漏洞一步步攻陷网站服务器?  Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程  简历在线制作网站免费版,如何创建个人简历?  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  ChatGPT 4.0官网入口地址 ChatGPT在线体验官网  Python进程池调度策略_任务分发说明【指导】  如何挑选最适合建站的高性能VPS主机?  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  Laravel Debugbar怎么安装_Laravel调试工具栏配置指南  Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  微信小程序 require机制详解及实例代码  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  微信小程序 五星评分(包括半颗星评分)实例代码  Laravel Admin后台管理框架推荐_Laravel快速开发后台工具  如何快速上传建站程序避免常见错误?  javascript读取文本节点方法小结  Python制作简易注册登录系统  如何在香港服务器上快速搭建免备案网站?  Laravel distinct去重查询_Laravel Eloquent去重方法  Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南  如何在腾讯云服务器快速搭建个人网站?  Python高阶函数应用_函数作为参数说明【指导】  Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives