Java实现克隆的三种方式实例总结

下面我将为你详细讲解如何实现Java克隆的三种方式。

1. Java实现克隆的三种方式

在Java中,对象的克隆可以通过直接复制或者序列化来完成。实现Java对象克隆一般有三种方式:

1.1. 浅克隆

浅克隆只复制了对象本身,不包括对象中的引用类型字段。假设有一个简单的Person类,它包括一个基本类型和一个引用类型字段:

public class Person implements Cloneable{
    private String name;
    private Integer age;
    private List<String> hobbies;

    //省略构造方法和get、set方法

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

如果使用浅克隆方法克隆出一个Person对象,那么hobbies字段只是复制了原始对象中引用的地址,而不是实际的引用对象本身。因此,对克隆对象中的hobbies字段的修改会影响原始对象。

下面是一个Person对象的浅克隆示例:

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person();
        p1.setName("张三");
        p1.setAge(20);
        List<String> hobbies = new ArrayList<>();
        hobbies.add("足球");
        hobbies.add("音乐");
        p1.setHobbies(hobbies);

        Person p2 = (Person) p1.clone();
        System.out.println("p1:" + p1);
        System.out.println("p2:" + p2);

        p2.setName("李四");
        p2.getHobbies().add("看书");

        System.out.println("p1:" + p1);
        System.out.println("p2:" + p2);
    }
}

输出结果:

p1:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p2:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p1:Person{name='张三', age=20, hobbies=[足球, 音乐, 看书]}
p2:Person{name='李四', age=20, hobbies=[足球, 音乐, 看书]}

1.2. 深克隆

深克隆会复制对象中的所有引用类型字段。假设有一个Order类,它包括一个基本类型字段和一个引用类型Hobby类型字段:

public class Order implements Cloneable {
    private String orderId;
    private Hobby hobby;

    //省略构造方法和get、set方法

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Order order = (Order)super.clone();
        order.setHobby((Hobby) hobby.clone());
        return order;
    }
}

若使用深克隆方式实现Order类对象的复制,则实际上是将原始对象中各引用指向对象的数据区域都复制过来了,因此修改了克隆对象中的引用类型字段不会影响原始对象。

下面是一个Order对象的深克隆示例:

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Order order1 = new Order();
        order1.setOrderId("20211014");
        Hobby hobby = new Hobby();
        hobby.setName("读书");
        order1.setHobby(hobby);

        Order order2 = (Order) order1.clone();
        System.out.println("order1:" + order1);
        System.out.println("order2:" + order2);

        order2.getHobby().setName("看电影");

        System.out.println("order1:" + order1);
        System.out.println("order2:" + order2);
    }
}

输出结果:

order1:Order{orderId='20211014', hobby=Hobby{name='读书'}}
order2:Order{orderId='20211014', hobby=Hobby{name='读书'}}
order1:Order{orderId='20211014', hobby=Hobby{name='读书'}}
order2:Order{orderId='20211014', hobby=Hobby{name='看电影'}}

1.3. 序列化克隆

序列化克隆会通过序列化和反序列化技术实现对象的克隆。要实现序列化克隆,需要让对象实现Serializable接口,并将对象序列化到一个流中,然后再从流中反序列化出一个新的对象。

下面是一个Person对象的序列化克隆示例:

public static <T extends Serializable> T clone(T obj) throws Exception {
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bout);
    oos.writeObject(obj);

    ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bin);
    T newObj = (T)ois.readObject();

    return newObj;
}

public static void main(String[] args) throws Exception {
    Person p1 = new Person();
    p1.setName("张三");
    p1.setAge(20);
    List<String> hobbies = new ArrayList<>();
    hobbies.add("足球");
    hobbies.add("音乐");
    p1.setHobbies(hobbies);

    Person p2 = clone(p1);
    System.out.println("p1:" + p1);
    System.out.println("p2:" + p2);

    p2.setName("李四");
    p2.getHobbies().add("看书");

    System.out.println("p1:" + p1);
    System.out.println("p2:" + p2);
}

输出结果:

p1:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p2:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p1:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p2:Person{name='李四', age=20, hobbies=[足球, 音乐, 看书]}

以上是实现Java克隆的三种方式,根据实际需要可以选择不同的方式进行对象的克隆。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现克隆的三种方式实例总结 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Spring Boot用户注册验证的实现全过程记录

    下面我将详细讲解如何实现“Spring Boot用户注册验证的实现全过程记录”,包含以下内容: 创建Spring Boot项目 添加依赖 实现用户注册 实现用户验证 完整示例1:使用Thymeleaf模板实现用户注册和验证 完整示例2:使用Vue前端框架和Spring Boot后端实现用户注册和验证 1. 创建Spring Boot项目 使用Intellij…

    Java 2023年5月20日
    00
  • Java多线程执行处理业务时间太久解决方法代码示例

    针对你提出的问题,我会给出一份详细讲解“Java多线程执行处理业务时间太久解决方法代码示例”的完整攻略,过程中会包含以下几个部分的内容: Java多线程执行处理业务时间太久的原因 解决Java多线程执行处理业务时间太久的解决方案 代码示例 为了更好的与你展开对话,接下来我会就每个部分分别进行详细说明。 Java多线程执行处理业务时间太久的原因 在Java多线…

    Java 2023年5月18日
    00
  • Java实现json数据处理的常用脚本分享

    下面是Java实现json数据处理的常用脚本分享的完整攻略: 一、前置知识 在学习Java实现json数据处理之前,我们需要先了解什么是JSON和Java中处理JSON数据的类库,如:Gson, Jackson等。 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于前后端数据传输。JSON主要由两种结构组成:键…

    Java 2023年5月26日
    00
  • 简述Java编程之关系操作符

    在讲解Java编程之关系操作符之前,先来了解一下什么是运算符。 运算符是指用于对一定数据类型的变量进行运算操作的一类特殊字符,可以分为算术运算符、关系运算符、逻辑运算符、位运算符等。 Java编程中的关系运算符主要用于比较两个变量之间的关系,得到的结果是boolean类型,即true或false。在Java中用于关系运算的符号有 ==、!=、>、&lt…

    Java 2023年5月26日
    00
  • 详解Java的Hibernate框架中的缓存与二级缓存

    详解Java的Hibernate框架中的缓存与二级缓存攻略 本攻略旨在详细讲解Java的Hibernate框架中的缓存与二级缓存,帮助读者了解Hibernate框架中的缓存机制和优化方式。 什么是Hibernate框架中的缓存? Hibernate框架中的缓存是指在应用程序与数据库之间的缓存层,即程序与数据库之间的缓存层,它能够在应用程序与数据库之间减少交互…

    Java 2023年5月20日
    00
  • hackathon 复盘:niche 海外软件工具正确的方法 6 个步骤

    上周末,去参加了北京思否 hackathon,两天时间内从脑暴 & 挖掘软件 IDEA -> Demo 研发路演,这次经历让我难忘。这里我的看法是每个开发者圈友,都应该去参加一次 hackathon ~ 做 niche 软件正确的方法 这边先说结论,如图。我认为 做 niche 软件正确的方法 或 6 个步骤 是: 发现用户的问题或痛点 明确问…

    Java 2023年4月22日
    00
  • 必须要学会的JMM与volatile

    下面我为你详细讲解必须要学会的JMM与volatile的完整攻略。 JMM介绍 JMM(Java Memory Model)即Java内存模型,用于规范Java程序中线程对共享变量的操作。JMM为Java程序中的线程提供可见性、有序性、原子性等保证,从而提高程序并发性能。 JMM提供的保证 可见性: 一个线程修改了共享变量的值,这个值的变化对其他线程是可见的…

    Java 2023年5月26日
    00
  • Java贪心算法超详细讲解

    Java贪心算法超详细讲解 什么是贪心算法 贪心算法是一种使用贪心策略的算法,它是一种在每一步选择中都采取在当前状态下最佳或最优的选择,从而导致结果是全局最优或最佳的算法思想。 与其他算法相比,贪心算法的时间复杂度一般比较低,通常来说是线性的时间复杂度,但是它的问题是不一定能够得到全局最优解。 贪心算法的步骤 贪心算法的步骤如下: 确定问题的最优子结构 设计…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部