前提:在Java语言中所有的类的都是缺省的继承Java语言中的Object类的,

protected native Object clone() throws CloneNotSupportedException;

它还是一个native的方法,大家都知道native的方法是非Java语言实现的代码,供Java语言调用,因为Java程序是运行在虚拟机上的,要想访问到比较低层的与操作系统相关的就没有办法了,只能由靠近操作系统的语言实现。

每一个对象直接或者间接的继承Object,因此他们都含有clone()方法,但是这个方法是Protected,所以不能在类外边访问。要想实现对一个对象的复制,就需要对clone()方法进行覆盖。

为什么要克隆?

克隆的对象可能包含一些已经修改过的属性,而new出来的对象都是初始化时候的值,所以当需要一个新的对象保存当前对象状态的时候就要靠clone()方法了。那么如果把这个对象的临时属性一个一个的赋值给新new出来的变量就会比较麻烦;而且clone()方法是非Java语言实现的更接近低层,所以速度比较快。

注意:我们常见的Object a=new Object();Object b;b=a;这种形式的代码复制的是引用,即对象在内存中的地址,a和b对象仍然指向了同一个对象。通过clone()方法复制的对象跟原来的对象是同时独立存在的。

如何实现克隆?

两种不同的克隆方法:浅克隆(shallowclone)和深克隆(deepclone) 。在Java语言中,数据类型分为基本数据类型和引用类型,其中引用数据类型主要包括类、接口、数组等复杂的数据类型。浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制。

一、浅克隆的一般步骤:

  • 被复制的类需要实现Clonable接口。该接口为标记接口,里边不含任何的方法。
  • 覆盖clone()方法,访问修饰符设为public,方法中调用super.clone()方法得到需要的复制对象。

  这就是浅克隆,两个对象引用分别指向的是不同的堆内存空间。这里我们能看到,在学生这个类里面的所有成员变量都是基本数据类型,所以这个时候使用浅克隆是完全没有问题的,因为成员变量不涉及到引用数据类型。

二、深克隆的一般步骤:

深克隆和浅克隆的区别就是在一个类里边如果有引用类型的变量的话,依然使用浅克隆的方法进行对象引用的复制,那么出现的结果就是对象里的引用类型变量只是变量的复制,实际上并没有为复制的引用类型变量重新开辟空间。所以,为了达到真正的复制对象,针对引用类型变量不单单是变量的复制,我们需要将引用类型变量可复制化,并且还要修改clone()方法。

Eg:在学生类里边加入地址类:

深克隆的一般步骤:

  • 当某一个类A是另一个类B的成员变量的时候,那么类A也要实现Clonable()这个接口,并且重写clone()方法。

  • 类B也要实现Clonable()这个接口,并且在类B的实现代码里边也要重写clone()方法。

浅克隆和深克隆的比较?

1、浅克隆:在前克隆中,如果原型对象的成员变量是值的类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量(引用类型)指向相同的内存地址。

2、深克隆:在深克隆中无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

简单地说就是在深克隆中,除了对象本身被复制外,对象所包含的成员变量也将复制。

注意:如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。

java基础知识总结--对象的克隆的更多相关文章

  1. Java基础知识(壹)

    写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...

  2. java基础知识小总结【转】

    java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...

  3. 学习android学习必备的java基础知识--四大内部类

    学习android必备的java基础知识--四大内部类 今天学习android课程,因为我的主专业是JAVA,但是兴趣班却有这其他专业的同学,学习android 需要具备一些java的基础知识,因此就 ...

  4. JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)

    本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...

  5. java基础知识回顾之---java String final类普通方法

    辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /*     * 按照面向对象的思想对字符串进行功能分类.     *      ...

  6. Java 基础知识(一)

    Java基础知识篇: 一.关键字解释 1. final:修饰非抽象类,非抽象方法和属性, 以及修饰方法参数,代表“无法改变的”.出于对设计或者效率的考虑使用该关键字. final类无法被继承,fina ...

  7. Java 基础知识总结

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.数据类型:  数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte  8位   (by ...

  8. 学习Spring必学的Java基础知识(1)----反射(转)

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

  9. 学习Spring必学的Java基础知识(1)----反射

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

随机推荐

  1. python--使用双向队列结构检查回文

    这个简单,队列可两边进两边出. # coding = utf-8 # 双向进出队列 class Deque: def __init__(self): self.items = [] def is_em ...

  2. 一脸懵逼学习Struts数据校验以及数据回显,模型驱动,防止表单重复提交的应用。

    1:Struts2表单数据校验: (1)前台校验,也称之为客户端校验,主要是通过Javascript编程的方式进行数据的验证. (2)后台校验,也称之为服务器校验,这里指的是使用Struts2通过xm ...

  3. iTOP4412环境搭建:arm-linux-gcc: 没有那个文件或目录

    系统:vmware下的ubuntu14.04 对于iTOP4412自己搭建环境,在source /root/.bashrc后发现还是没有正常,调用arm-linux-gcc -v提示没有那个文件或目录 ...

  4. asp.net core 2.0 webapi集成signalr

    asp.net core 2.0 webapi集成signalr   在博客园也很多年了,一直未曾分享过什么东西,也没有写过博客,但自己也是汲取着博客园的知识成长的: 这两天想着不能这么无私,最近.N ...

  5. eclipse 编辑代码区字体大小

    wiondow-->preferences-->general-->appearance-->colors and fonts-->java-->java edit ...

  6. Coolpy网络部署说明(局域网)

    本文将介绍Coolpy第一种方案的网络部署方法.以方便大家学习如何让coolpy设备部署到相应的应用场景中.本例将以水星MW310R无线路由器作为演示路由器. 1.局域网部署 即coolpy设备=&g ...

  7. Flink的流处理--KeyBy

    逻辑上将一个流分成不相交的分区,每个分区包含相同键的元素.在内部,这是通过散列分区来实现的 object Keyby { def main(args: Array[String]): Unit = { ...

  8. 使用ycsb对hbase1.4.9 benchmark

    Ycsb下载地址:https://github.com/brianfrankcooper/YCSB/releases 目前测试hbase1.4.9,因此下载ycsb-hbase14-binding-0 ...

  9. M. Subsequence 南昌邀请赛

    链接: https://nanti.jisuanke.com/t/38232 先给出一个s母串 然后给出n个子串 判断是否为母串的子序列 3000ms  2993ms过的.... 蒻鲫的代码: 建立表 ...

  10. day23 面向对象 函数和方法区分

    最近两周内容大概回顾: # 文件操作 # # 模块:random,序列化模块,时间模块,collections,re,os,sys # 模块与包的概念和导入方法 # 写代码的规范 # 正则表达式 # ...