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日

相关文章

  • Java Web程序实现返回JSON字符串的方法总结

    下面就是针对“Java Web程序实现返回JSON字符串的方法总结”的完整攻略: 1.使用Jackson库 在Java Web程序中,可以使用Jackson库将Java对象转换为JSON字符串。使用Jackson库需要添加依赖,Maven中添加如下依赖: <dependency> <groupId>com.fasterxml.jack…

    Java 2023年5月26日
    00
  • php中session退出登陆问题

    下面是关于PHP中Session退出登录问题的完整攻略: 1. 什么是Session退出登录问题 在使用Session管理用户身份认证时,通常会使用Session存储用户登录状态信息,当用户点击“退出登录”按钮或删除浏览器Cookie时,需要销毁Session并将用户的登录状态重置为未登录。而PHP中的Session退出登录问题,指的是在进行Session销…

    Java 2023年6月16日
    00
  • MyBatis与SpringMVC相结合实现文件上传、下载功能

    下面是关于“MyBatis与SpringMVC相结合实现文件上传、下载功能”的完整攻略,包含两个示例说明。 MyBatis与SpringMVC相结合实现文件上传、下载功能 在Web应用程序中,文件上传和下载是常见的功能。本文将介绍如何使用MyBatis和SpringMVC相结合实现文件上传和下载功能。 文件上传 1. 添加依赖 首先,我们需要添加以下依赖: …

    Java 2023年5月17日
    00
  • 详解Spring Security中获取当前登录用户的详细信息的几种方法

    下面是详解Spring Security中获取当前登录用户的详细信息的几种方法的完整攻略。 什么是Spring Security? Spring Security是Spring框架的安全认证框架,支持 Web 安全、方法级安全等多种安全场景。通过Spring Security,我们能够实现身份认证、资源授权等各种安全特性,从而保障我们的应用系统在开放网络环境…

    Java 2023年6月3日
    00
  • Java之JSP教程九大内置对象详解(上篇)

    下面我来详细讲解“Java之JSP教程九大内置对象详解(上篇)”的完整攻略。 什么是九大内置对象? JSP的九大内置对象是指在JSP页面中JSP引擎默认提供的九个对象,包括request、response、session、application、page、out、config、pageContext、exception对象。 request对象 reques…

    Java 2023年5月26日
    00
  • 使用SpringBoot+AOP实现可插拔式日志的示例代码

    下面是使用SpringBoot+AOP实现可插拔式日志的完整攻略。 什么是SpringBoot+AOP Spring AOP(Aspect Oriented Programming)是Spring框架中的一个重要模块,用于将额外的行为(横切逻辑)注入到系统中的特定点。SpringBoot是Spring框架的一个特殊版本,通过预先配置好常用的Bean并提供自动…

    Java 2023年5月20日
    00
  • Spring SpringMVC,Spring整合MyBatis 事务配置的详细流程

    下面是关于Spring、SpringMVC和MyBatis整合以及事务配置的详细流程,包含两个示例说明。 Spring、SpringMVC和MyBatis整合以及事务配置 Spring、SpringMVC和MyBatis是Java Web应用程序开发中常用的框架。在本文中,我们将介绍如何将这三个框架整合在一起,并配置事务管理。 步骤1:添加依赖 首先,我们需…

    Java 2023年5月17日
    00
  • Java如何基于poi操作Wold工具类

    下面是Java基于poi操作Word的完整攻略。 1. 简介 Apache POI是一个为Microsoft Office格式(如.docx和.xlsx)提供Java API的开源项目,其中包括对Word文档的操作。本攻略将重点介绍Java如何基于poi操作Word的方法。 2. 准备工作 在进行poi操作Word之前,需要先下载poi包,并导入到项目中。 …

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