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

yizhihongxing

下面我将为你详细讲解如何实现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日

相关文章

  • 现代高效的java构建工具gradle的快速入门

    下面我来为你详细讲解现代高效的 Java 构建工具 Gradle 的快速入门的完整攻略。 什么是 Gradle? Gradle 是一款由 Groovy 编写的构建工具,在 2012 年开始受到广泛关注。它可以用于构建 Java 项目,也可以用于构建其他类型的项目。 与其他构建工具相比,Gradle 更加灵活、易于定制,并具有更强的性能。它采用了一种基于任务(…

    Java 2023年5月26日
    00
  • SpringBoot整合Redis、ApachSolr和SpringSession的示例

    下面是”SpringBoot整合Redis、ApachSolr和SpringSession的示例”的完整攻略,其中包括两个示例。 1. 环境搭建 首先,在我们开始之前,确保你已经正确地安装了Java、Maven、Redis、ApachSolr和SpringBoot。 1.1 安装Redis 可以在Redis官网上,下载并安装最新版的Redis。如果你使用的是…

    Java 2023年5月20日
    00
  • Spring Boot2解决idea console 控制台输出乱码的问题

    针对Spring Boot 2解决IDEA控制台输出乱码的问题,我们需要进行以下步骤: 步骤一:在application.properties文件中加入配置项 在Spring Boot2的应用程序中可以在application.properties文件中增加以下配置项: # 配置控制台编码为utf-8 spring.output.ansi.enabled=a…

    Java 2023年5月20日
    00
  • 使用Spring Boot的原因解析

    使用Spring Boot的原因解析 前言 Spring Boot 是 Spring 家族的一个全新项目,它通过提供自动配置、快速开发等一系列优化,使得 Spring 应用的开发更加简单、快速、便捷。那么为什么我们要选择使用 Spring Boot 呢?下面本文将从以下几个方面为大家详细介绍 Spring Boot 的使用原因。 解析 1. 自动配置 Spr…

    Java 2023年5月15日
    00
  • Java利用Jackson轻松处理JSON序列化与反序列化

    下面是“Java利用Jackson轻松处理JSON序列化与反序列化”的完整攻略。 简介 在Java开发中,我们常常需要对JSON数据进行序列化和反序列化操作。JSON是一种轻量级的数据交换格式,常用于数据传递和存储。而Jackson是一款高效、灵活、功能强大的Java库,用于处理JSON数据。本文将介绍如何使用Jackson来进行JSON序列化和反序列化操作…

    Java 2023年5月26日
    00
  • springboot项目配置多个kafka的示例代码

    下面是关于springboot项目配置多个kafka的攻略。 配置pom.xml文件 首先,在pom.xml文件中添加kafka和spring-kafka的依赖: <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spri…

    Java 2023年5月20日
    00
  • 详细介绍SpringCloud之Ribbon

    详细介绍SpringCloud之Ribbon 什么是Ribbon? Ribbon是Netflix开源项目之一,主要功能是提供客户端的负载均衡算法及服务调用。它是Spring Cloud体系中较为重要的组件,可以与Eureka、Consul、Zookeeper等注册中心组合使用,实现服务间的调用与负载均衡。 Ribbon的负载均衡算法 Ribbon提供了多种负…

    Java 2023年6月16日
    00
  • 解决Springboot-application.properties中文乱码问题

    解决 Springboot-application.properties 中文乱码问题需要遵循以下步骤: 步骤一:修改 IDE 编码 在开始修改 Springboot-application.properties 文件之前,首先需要确保 IDE 的编码设置正确。因为如果 IDE 的编码设置不正确,无论怎么修改 Springboot-application.p…

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