一、Object类中clone的实现。

二、clone详解。

看,clone()方法又是一个被声明为native的方法,因此,我们知道了clone()方法并不是Java的原生方法,具体的实现是有C/C++完成的。clone英文翻译为"克隆",其目的是创建并返回此对象的一个副本。形象点理解,这有一辆科鲁兹,你看着不错,想要个一模一样的。你调用此方法即可像变魔术一样变出一辆一模一样的科鲁兹出来。配置一样,长相一样。但从此刻起,原来的那辆科鲁兹如果进行了新的装饰,与你克隆出来的这辆科鲁兹没有任何关系了。你克隆出来的对象变不变完全在于你对克隆出来的科鲁兹有没有进行过什么操作了。Java术语表述为:clone函数返回的是一个引用,指向的是新的clone出来的对象,此对象与原对象分别占用不同的堆空间。

明白了clone的含义后,接下来看看如果调用clone()函数对象进行此克隆操作。

首先看一下下面的这个例子:

 1 package com.corn.objectsummary;
2
3 import com.corn.Person;
4
5 public class ObjectTest {
6
7 public static void main(String[] args) {
8
9 Object o1 = new Object();
10 // The method clone() from the type Object is not visible
11 Object clone = o1.clone();
12 }
13
14 }

例子很简单,在main()方法中,new一个Oject对象后,想直接调用此对象的clone方法克隆一个对象,但是出现错误提示:"The method clone() from the type Object is not visible"

why? 根据提示,第一反应是ObjectTest类中定义的Oject对象无法访问其clone()方法。回到Object类中clone()方法的定义,可以看到其被声明为protected,估计问题就在这上面了,protected修饰的属性或方法表示:在同一个包内或者不同包的子类可以访问。显然,Object类与ObjectTest类在不同的包中,但是ObjectTest继承自Object,是Object类的子类,于是,现在却出现子类中通过Object引用不能访问protected方法,原因在于对"不同包中的子类可以访问"没有正确理解。

"不同包中的子类可以访问",是指当两个类不在同一个包中的时候,继承自父类的子类内部且主调(调用者)为子类的引用时才能访问父类用protected修饰的成员(属性/方法)。 在子类内部,主调为父类的引用时并不能访问此protected修饰的成员。!(super关键字除外)

于是,上例改成如下形式,我们发现,可以正常编译:

 1 package com.corn.objectsummary;
2
3
4 public class ObjectTest {
5
6 public static void main(String[] args) {
7 ObjectTest ot1 = new ObjectTest();
8
9 try {
10 ObjectTest ot2 = (ObjectTest) ot1.clone();
11 } catch (CloneNotSupportedException e) {
12 // TODO Auto-generated catch block
13 e.printStackTrace();
14 }
15 }
16
17 }

是的,因为此时的主调已经是子类的引用了。

上述代码在运行过程中会抛出"java.lang.CloneNotSupportedException",表明clone()方法并未正确执行完毕,问题的原因在与Java中的语法规定:

clone()的正确调用是需要实现Cloneable接口,如果没有实现Cloneable接口,并且子类直接调用Object类的clone()方法,则会抛出CloneNotSupportedException异常。

Cloneable接口仅是一个表示接口,接口本身不包含任何方法,用来指示Object.clone()可以合法的被子类引用所调用。

于是,上述代码改成如下形式,即可正确指定clone()方法以实现克隆。

 1 package com.corn.objectsummary;
2
3 public class ObjectTest implements Cloneable {
4
5 public static void main(String[] args) {
6
7 ObjectTest ot1 = new ObjectTest();
8
9 try {
10 ObjectTest ot2 = (ObjectTest) ot1.clone();
11 System.out.println("ot2:" + ot2);
12 } catch (CloneNotSupportedException e) {
13 // TODO Auto-generated catch block
14 e.printStackTrace();
15 }
16 }
17
18 }

三、克隆专讲。

1、

2、

3、

Object之clone的更多相关文章

  1. Object类clone方法的自我理解

    网上搜帖: clone()是java.lang.Object类的protected方法,实现clone方法: 1)类自身需要实现Cloneable接口 2)需重写clone()方法,最好设置修饰符mo ...

  2. Cloneable接口和Object的clone()方法

    为什么要克隆 为什么要使用克隆,这其实反映的是一个很现实的问题,假如我们有一个对象: public class SimpleObject implements Cloneable { private ...

  3. 方法object面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆

    时间紧张,先记一笔,后续优化与完善.     每日一道理 翻开早已发黄的页张,试着寻找过去所留下的点点滴滴的足迹.多年前的好友似乎现在看来已变得陌生,匆忙之间,让这维持了多年的友谊变淡,找不出什么亲切 ...

  4. JavaScript 中的对象深度复制(Object Deep Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法. JavaScript中的赋值,其实并不是复制对象,而是类似`c/c++`中的引用(或指针),因此下面的代码中改变对象b ...

  5. JS 克隆Object.prototype.Clone

    我们知道,在js中,当object作为参数传递到函数中进行处理后,实际上是修改了传入的对象本身(或者说是对象的引用),但很多时候我们并不希望函数去修改我们的这些对象参数,这就需要使用到对象的克隆,我们 ...

  6. 为什么阿里Java手册推荐慎用 Object 的 clone 方法来拷贝对象

    图片若无法显示,可至掘金查看https://juejin.im/post/5d425230f265da039519d248 前言 在阿里Java开发手册中,有这么一条建议:慎用 Object 的 cl ...

  7. [置顶] 顿悟JAVA,自己实现Object的Clone的约束关系(上)

    因protected 的理解,顿悟一些JAVA的原理,模拟了Object类的子类为什么在调用clone方法前实现Cloneable接口. 这里不解释 ,上代码先. 运行效果 文件结构 调用类 pack ...

  8. 【转】JavaScript中的对象复制(Object Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b. ...

  9. 关于clone(java.lang.Object)重写

    1. 需要实现接口java.lang.Cloneable 2. 重写java.lang.Object的clone 3. clone访问权限扩大为public 4. 不实现(java.lang.Clon ...

随机推荐

  1. sencha touch 分享到微博扩展

    扩展代码: /* *分享到微博 */ Ext.define('ux.WeiboPicker', { extend: 'Ext.Picker', xtype: 'weiboPicker', config ...

  2. 添加Net4CollectionTypeFactory的原因

    .NET4.0已经实现了该功能 http://jahav.com/blog/nhibernate-using-net-4-iset/ NHibernate using .NET 4 ISet 0 Co ...

  3. ToStringBuilder类

    文章来源:http://blog.csdn.net/zhaowen25/article/details/39521899 apache的commons-lang3的工具包里有一个ToStringBui ...

  4. React Native ——入门环境搭配以及简单实例

    一.Homebrew 是OS X 的套件管理器. 首先我们需要获取 Homebrew ruby -e "$(curl -fsSL https://raw.githubusercontent. ...

  5. Mongodb高级篇-性能优化

    1.监控 mongodb可以通过profile来监控数据,进行优化. 查看当前是否开启profile功能用命令:db.getProfilingLevel()返回level等级,值为0|1|2,分别代表 ...

  6. 8.11 数据库ORM(5)

    2018-8-11 20:43:52 昨天从俺弟家回来了. 和俺弟聊天发现,他一直停留在自己目前的圈子,自己觉得很牛逼,比别人高人一等,, 读书无用论,,可以用 幸存者偏激理论 大概就是这个 可以否决 ...

  7. js之数据类型及类型转换

    一.数据类型 js中的数据类型:      5种基础类型:Undefined,Null,Boolean,Number,String      1种复合类型:Object(对象包括数组,函数等)   1 ...

  8. 获取验证码随机字符串@return string $captcha,随机验证码文字

    <?php//验证码工具类class Captcha{//属性private $width;private $height;private $fontsize;private $pixes;pr ...

  9. Saltstack实战之无master和多master

    如果不想依赖master可以设置为无master vim /etc/salt/minion 就可以通过minion来安装一个salt-master了(下来查资料做,关闭salt-minion进程因为不 ...

  10. POJ-2029 Get Many Persimmon Trees(动态规划)

    Get Many Persimmon Trees Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3987 Accepted: 2 ...