Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >java clone

java clone

作者头像
LiosWong
发布于 2018-10-29 09:44:56
发布于 2018-10-29 09:44:56
72900
代码可运行
举报
文章被收录于专栏:后端沉思录后端沉思录
运行总次数:0
代码可运行

简介

实现Cloneable接口的类才可以被克隆,如果不实现该接口,调用Object clone方法会报CloneNotSupportedException:

InvokingObject's clone method on an instance that does not implement theCloneableinterface results in the exceptionCloneNotSupportedExceptionbeing thrown.

分类

  1. 浅克隆 指拷贝对象时仅拷贝对象本身中的基本变量,而不拷贝对象包含的引用指向的对象
  2. 深克隆 不仅拷贝对象本身中的基本变量,而且还拷贝对象中包含的引用指向的所有对象

说明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.lios.clone;

/**
 * @author LiosWong
 * @description
 * @date 2018/6/25 上午4:11
 */
public class Person implements Cloneable {
    private String name;

    private Worker worker;

    public Person(String name, Worker worker) {
        this.name = name;
        this.worker = worker;
    }

    public String getName() {
        return name;
    }

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

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

    public static void main(String[] args) {
        Person p = new Person("lios", new Worker("worker", 25));
        Person p1 = p;
        System.out.println("p:toString:" + p + ",hashCode:" + p.hashCode() + ",Worker:" + p.getWorker().hashCode() + ",name=" + p.getName().hashCode());
        System.out.println("p1:toString:" + p1 + ",hashCode:" + p1.hashCode() + ",Worker:" + p1.getWorker().hashCode() + ",name=" + p1.getName().hashCode());
        System.out.println(p1);


        System.out.println("=====================");

        try {
            Person p2 = (Person) p.clone();
            System.out.println("p:Worker:name:"+p.getWorker().getName());
            System.out.println("p1:Worker:name:"+p1.getWorker().getName());
            System.out.println("p2:Worker:name:"+p2.getWorker().getName());


            System.out.println("p2:toString:" + p2 + ",hashCode:" + p2.hashCode() + ",Worker:" + p2.getWorker().hashCode() + ",name=" + p2.getName().hashCode());
            p.getWorker().setName("workp");
            p.setName("cc");
            System.out.println("p2:toString:" + p2 + ",hashCode:" + p2.hashCode() + ",Worker:" + p2.getWorker().hashCode() + ",name=" + p2.getName().hashCode());
            System.out.println("p:Worker:name:"+p.getWorker().getName());
            System.out.println("p1:Worker:name:"+p1.getWorker().getName());
            System.out.println("p2:Worker:name:"+p2.getWorker().getName());
            System.out.println("p:"+p.getName());
            System.out.println("p1:"+p1.getName());
            System.out.println("p2:"+p2.getName());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

    public Worker getWorker() {
        return worker;
    }

    public Person setWorker(Worker worker) {
        this.worker = worker;
        return this;
    }

    public static class Worker implements Cloneable {
        private String name;
        private Integer age;

        public Worker(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

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

        public String getName() {
            return name;
        }

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

        public Integer getAge() {
            return age;
        }

        public Worker setAge(Integer age) {
            this.age = age;
            return this;
        }
    }
}

执行结果为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
p:toString:com.lios.clone.Person@2401f4c3,hashCode:604107971,Worker:123961122,name=3321889
p1:toString:com.lios.clone.Person@2401f4c3,hashCode:604107971,Worker:123961122,name=3321889
com.lios.clone.Person@2401f4c3
=====================
p:Worker:name:worker
p1:Worker:name:worker
p2:Worker:name:worker
p2:toString:com.lios.clone.Person@4926097b,hashCode:1227229563,Worker:123961122,name=3321889
p2:toString:com.lios.clone.Person@4926097b,hashCode:1227229563,Worker:123961122,name=3321889
p:Worker:name:workp
p1:Worker:name:workp
p2:Worker:name:workp
p:cc
p1:cc
p2:lios

发现p,p1所有的值都是一致的,当对象p中重置name属性的值、Worker属性中name的值后,p、p1、p2中属性Worker中name属性值都改变了且值相同,但是p2中的name属性值没有变化,下面用图描述:

p1与p指向堆中的同一块内存区域,p2虽然与p、p1不是指向同一块内存区域,但是它们中的Worker属性都引用同一块内存区域,其实这就是浅克隆,修改上面clone方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    protected Object clone() throws CloneNotSupportedException {
         Person p = (Person) super.clone();
         p.worker = (Worker) p.getWorker().clone();
         return p;
    }

再执行,结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
p:toString:com.lios.clone.Person@2401f4c3,hashCode:604107971,Worker:123961122,name=3321889
p1:toString:com.lios.clone.Person@2401f4c3,hashCode:604107971,Worker:123961122,name=3321889
com.lios.clone.Person@2401f4c3
=====================
p:Worker:name:worker
p1:Worker:name:worker
p2:Worker:name:worker
p2:toString:com.lios.clone.Person@4926097b,hashCode:1227229563,Worker:1982791261,name=3321889
p2:toString:com.lios.clone.Person@4926097b,hashCode:1227229563,Worker:1982791261,name=3321889
p:Worker:name:workp
p1:Worker:name:workp
p2:Worker:name:worker
p:cc
p1:cc
p2:lios

发现此时p2中属性Worker中的name属性值没有改变,仅仅p、p1中属性Worker中的name属性值改变了,图示:

上面就是深克隆

总结

  1. 对象被clone必须实现Cloneable接口
  2. 深克隆需拷贝对象中包含的引用指向的所有对象
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端沉思录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java基础——clone()方法浅析
一、clone的概念    clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那么在java语言中,有几种方式可以创建对象呢?  使用new操作符创建一个对象 使用clone方法复制一个对象    那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后
mukekeheart
2018/02/27
7890
Java基础——clone()方法浅析
23种设计模式之原型模式
原型模式 定义: 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。 主要用于创建对象 原型模式实现只需要实现一个接口 重写clone()方法 。 我们实现中 会有深拷贝和浅拷贝两种情况。 浅克隆 创建一个羊类 作为prototype public class Sheep{ /** * name名字 * creatTime 创建时间 */ private String name; private Date creatTime; pu
暴躁的程序猿
2022/03/23
2040
23种设计模式之原型模式
Java设计模式之原型模式
现在有一只羊,姓名为:tom,年龄为:1,颜色为:白色,请编写程序创建和tom羊属性完全相同的10只羊。
shaoshaossm
2022/12/27
2370
一篇文章带你了解设计模式之原型模式
现在有一只羊tom,姓名为: tom, 年龄为:1,颜色为:白色,请编写程序创建和tom羊 属性完全相同的10只羊
@派大星
2023/06/28
1480
一篇文章带你了解设计模式之原型模式
第三阶段-Java常见对象:【第一章 Object类】
在讲解Object类之前,我们不得不简单的提一下什么是API,先贴一组百度百科的解释:
BWH_Steven
2019/08/09
4540
设计模式之原型模式
创建型模式之原型模式 定义 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式是实现了一
爱撒谎的男孩
2018/05/25
4400
好似你,饼印咁:原型模式、浅拷贝与深拷贝
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。大概意思就是:允许一个对象再创建另外一个可定制的对象,根本无需知道对象创建的细节。其工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。其UML类图如下:
BUG弄潮儿
2021/01/18
3300
好似你,饼印咁:原型模式、浅拷贝与深拷贝
11.JAVA-Object类之finalize(),clone(),toString()等方法覆写
Object类是一个特殊的类,是所有类(包括数组,接口 )的父类,如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类,所以可以通过向上转型的方法使用类型为Object的变量指向任意类型的对象。
诺谦
2019/05/24
5200
图解Java设计模式之原型模式
现在有一只羊tom,姓名为 : tom,年龄为 :1,颜色为 :白色,请编写程序创建和tom羊属性完全相同的10只羊。
海仔
2020/03/19
4900
图解Java设计模式之原型模式
java对象拷贝
java赋值是复制对象引用,如果我们想要得到一个对象的副本,使用赋值操作是无法达到目的的:
pollyduan
2019/11/04
2.3K0
面试官:你知道对象的克隆原理吗?
我们把前面创建的UserDto对象引用复制给userDto了,然后又对对象中的两个属性进行重新赋值,userDto1也会随着赋值的。这就是所谓的浅克隆(浅复制)。
田维常
2020/12/14
5160
Java设计模式(五)----原型模式
原型模式(Prototype) 一、概述 二、结构 三、浅度克隆和深度克隆  浅度克隆  深度克隆 一、概述  定义:原型模式属于对象的创建模式。通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。简言之:就是复制粘贴。这就是选型模式的用意。 二、结构 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype类需要具备以下两个条件: 1、实现Cloneable接口。在java语言有一个
汤高
2018/01/11
6980
Java设计模式(五)----原型模式
深入浅出| java中的clone方法
clone,有人称之为克隆,有人称之为复制,其实都是同一个东西 本文称之为"克隆",毕竟人家方法名叫"clone"
KEN DO EVERTHING
2019/01/17
9980
作为所有类的顶层父类,没想到Object的魔力如此之大!
在上一篇博文中我们提到了Java面向对象的四大特性,其中谈及“抽象”特性时做了一个引子,引出今天的主人公Object,作为所有类的顶级父类,Object被视为是James.Gosling的哲学思考,它高度概括了事务的自然与社会行为。
JavaBuild
2024/05/27
1490
作为所有类的顶层父类,没想到Object的魔力如此之大!
详解Java中的clone方法:原型模式
clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那么在java语言中,有几种方式可以创建对象呢?
哲洛不闹
2018/09/19
7760
详解Java中的clone方法:原型模式
java设计模式(2) 建造者模式,深复制与浅复制
建造者模式 就是建造不同的东西,但是基本流程不变,将复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 //构建产品 public class Person { private String head; private String body; private String foot; public String getHead() { return head; } public void setHead(String head) { this.head = head; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getFoot() { return foot; } public void setFoot(String foot) { this.foot = foot; }
曼路
2018/10/18
7230
java设计模式(2) 建造者模式,深复制与浅复制
深入浅出Java中的clone克隆方法,写得太棒了!
作者:张纪刚 blog.csdn.net/zhangjg_blog/article/details/18369201/
Java技术栈
2019/07/08
3250
Java漫谈-深拷贝与浅拷贝
2、运用反射手段创建对象,调用java.lang.Class 或者 java.lang.reflect.Constructor 类的newInstance()实例方
WindCoder
2018/09/19
3.2K0
Java中clone方法的使用
  在实际编程过程中,我们常常要遇到这种情况:有一个对象object1,在某一时刻object1中已经包含了一些有效值,此时可能会需要一个和object1完全相同新对象object2,并且此后对object2任何改动都不会影响到object1中的值,也就是说,object1与object2是两个独立的对象,但object2的初始值是由object1对象确定的。在Java语言中,用简单的赋值语句是不能满足这种需 求的。要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。
Kevin_Zhang
2019/02/20
8210
工作三年,小胖连 Clone 源码都没读过?真的菜!
哈喽,我是狗哥。这是 Java 源码剖析的第三篇。克隆这个知识点在工作中使用不多,很容易被人忽略。但是面试中的面试官就很常问,因此小伙伴们还是要了解下。另外前两篇的链接在这里有兴趣的小伙伴可以看看:
JavaFish
2021/02/03
3940
工作三年,小胖连 Clone 源码都没读过?真的菜!
相关推荐
Java基础——clone()方法浅析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验