clone方法会返回该实例对象的一个副本,通常情况下x.clone() != x || x.clone().getClass() == x.getClass() || x.clone().equals(x)也为真。但不严格要求,我们能够通过重写该方法来覆盖。

protected native Object clone() throws CloneNotSupportedException;

能够看到。clone是一个本地方法,可能会抛出CloneNotSupportedException异常,什么情况下会抛出呢?

/*** A class implements the <code>Cloneable</code> interface to* indicate to the {@link java.lang.Object#clone()} method that it* is legal for that method to make a* field-for-field copy of instances of that class.* <p>* Invoking Object's clone method on an instance that does not implement the* <code>Cloneable</code> interface results in the exception* <code>CloneNotSupportedException</code> being thrown.* <p>* By convention, classes that implement this interface should override* <tt>Object.clone</tt> (which is protected) with a public method.* See {@link java.lang.Object#clone()} for details on overriding this* method.* <p>* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.* Therefore, it is not possible to clone an object merely by virtue of the* fact that it implements this interface.  Even if the clone method is invoked* reflectively, there is no guarantee that it will succeed.** @author  unascribed* @see     java.lang.CloneNotSupportedException* @see     java.lang.Object#clone()* @since   JDK1.0*/
public interface Cloneable {
}

说明中写到。假设该对象未实现Cloneable 接口。那么当实例调用clone方法时。就会抛出该异常。
以下看Object中对于clone方法的描写叙述。

    /*** Creates and returns a copy of this object.  The precise meaning* of "copy" may depend on the class of the object. The general* intent is that, for any object {@code x}, the expression:* <blockquote>* <pre>* x.clone() != x</pre></blockquote>* will be true, and that the expression:* <blockquote>* <pre>* x.clone().getClass() == x.getClass()</pre></blockquote>* will be {@code true}, but these are not absolute requirements.* While it is typically the case that:* <blockquote>* <pre>* x.clone().equals(x)</pre></blockquote>* will be {@code true}, this is not an absolute requirement.* <p>* By convention, the returned object should be obtained by calling* {@code super.clone}.  If a class and all of its superclasses (except* {@code Object}) obey this convention, it will be the case that* {@code x.clone().getClass() == x.getClass()}.* <p>* By convention, the object returned by this method should be independent* of this object (which is being cloned).  To achieve this independence,* it may be necessary to modify one or more fields of the object returned* by {@code super.clone} before returning it.  Typically, this means* copying any mutable objects that comprise the internal "deep structure"* of the object being cloned and replacing the references to these* objects with references to the copies.  If a class contains only* primitive fields or references to immutable objects, then it is usually* the case that no fields in the object returned by {@code super.clone}* need to be modified.* <p>* The method {@code clone} for class {@code Object} performs a* specific cloning operation. First, if the class of this object does* not implement the interface {@code Cloneable}, then a* {@code CloneNotSupportedException} is thrown. Note that all arrays* are considered to implement the interface {@code Cloneable} and that* the return type of the {@code clone} method of an array type {@code T[]}* is {@code T[]} where T is any reference or primitive type.* Otherwise, this method creates a new instance of the class of this* object and initializes all its fields with exactly the contents of* the corresponding fields of this object, as if by assignment; the* contents of the fields are not themselves cloned. Thus, this method* performs a "shallow copy" of this object, not a "deep copy" operation.* <p>* The class {@code Object} does not itself implement the interface* {@code Cloneable}, so calling the {@code clone} method on an object* whose class is {@code Object} will result in throwing an* exception at run time.** @return     a clone of this instance.* @exception  CloneNotSupportedException  if the object's class does not*               support the {@code Cloneable} interface. Subclasses*               that override the {@code clone} method can also*               throw this exception to indicate that an instance cannot*               be cloned.* @see java.lang.Cloneable*/protected native Object clone() throws CloneNotSupportedException;

当中提到的重写clone方法的几个注意点
1. 数组视为自己主动实现了Cloneable接口;
2. 非数组类型,使用clone方法,须要实现Cloneable接口。否则会抛出异常;
3. 非数组类型,克隆时,会新创建一个该类型的实例,并将被克隆对象实例的状态复制给新创建对象。而且这是一个浅克隆-(影子克隆——shallow copy),而不是deep copy;
4. 重写clone方法时。首先首先首先须要调用父类的clone方法。

那么问题来了。什么是shallow copy?而deep copy又是什么?

上样例:

public class Test {public static void main(String[] args) throws CloneNotSupportedException {People people = new People("zjh", '男', 21, new Cloth(COLOR.WHITE  , "XXL"));     People clone = (People) people.clone();System.out.println("people == clone : " + (people == clone));System.out.println("people.getCloth() == clone.getCloth() : "+ (people.getCloth() == clone.getCloth()));System.out.println("people.getAge() == clone.getAge() : "+(people.getAge() == clone.getAge()));System.out.println("people.getName() == clone.getName() : "+(people.getName() == clone.getName()));}
}
class People implements Cloneable{private String name;private char sex;private int age;private Cloth cloth;/** * {@inheritDoc}.*/@Overrideprotected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubreturn super.clone();}...若干getter/setter方法}
class Cloth{private COLOR color;private String size;/*** 构造函数.* * @param color* @param size*/public Cloth(COLOR color, String size) {super();this.color = color;this.size = size;}   enum COLOR {RED,WHITE,BLACK,GREEN,BLUE}
}

执行结果:

people == clone : false
people.getCloth() == clone.getCloth() : true
people.getSex() == clone.getSex() : true
people.getName() == clone.getName() : true

age,sex。name比較为真还能理解,为什么people.getCloth() == clone.getCloth() 也是true呢?又做了以下的測试。

 people.getCloth().setColor(COLOR.BLACK);System.out.println(clone.getCloth().getColor());

执行结果:

BLACK

如今已经能确定,people和它的克隆对象clone中的cloth引用指向了同一个Cloth实例。这就是“shallow copy”。那么想要“deep copy”。那么就须要在重写方法的时候,同一时候调用对象属性的克隆方法(要求该属性对象也须要实现Cloneable)。

clone方法改动例如以下:

    protected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubPeople clone =    (People) super.clone();clone.setCloth((Cloth)cloth.clone());return clone;}

再执行上面的測试程序:

people == clone : false
people.getCloth() == clone.getCloth() : false
people.getAge() == clone.getAge() : true
people.getSex() == clone.getSex() : true
people.getName() == clone.getName() : true

Object对象具体解释(二)之clone相关推荐

  1. Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、

    1:Scala之函数式编程学习笔记: 1:Scala函数式编程学习:1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法:class User {private v ...

  2. php object 对象不存在。增加对象_PHP开发自己的框架,这些知识点不能错过

    一.PHP常用的四种数据结构 简介:spl是php的一个标准库. <?php//spl(php标准库)数据结构/*** 栈(先进后出)*/ $stack = new SplStack(); $s ...

  3. OpenGL ES 名词解释(二)

    目录 一.前言 二.坐标系 1.屏幕坐标系 2.纹理坐标系 3.顶点坐标系 4.图像坐标系 三.混合 四.变换矩阵 1.平移 2.旋转 3.缩放 4.矩阵组合顺序 五.投影矩阵 1.正交投影 2.透视 ...

  4. JavaScript:对Object对象的一些常用操作总结

    JavaScript对Object对象的一些常用操作总结. 一.Object.assign() 1.可以用作对象的复制 var obj = { a: 1 }; var copy = Object.as ...

  5. linq结果转换object_【JavaScript 教程】标准库—Object 对象

    作者 | 阮一峰 1.概述 JavaScript 原生提供Object对象(注意起首的O是大写),本章介绍该对象原生的各种方法. JavaScript 的所有其他对象都继承自Object对象,即那些对 ...

  6. localStorage、sessionStorage本地存取Object 对象 - 代码篇

    文章目录 localStorage.sessionStorage本地存取Object 对象 - 代码篇 打印截图: 一. localStorage 实例: 1.1. 重要代码 · 片段如下: 二.se ...

  7. 【Java】Java 的Object对象你真的懂了吗

    1.概述 原文:https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247484210&idx=1&sn=9d40e2 ...

  8. 第三周阶段性小结——Object对象、String类、StringBuffer、StringBuilder、System、Runtime、Date...

    一.Object对象 1.object 类的常用方法: Object类是所有类的父类,java中所有的类都直接或间接地继承自Object类,即使没有显示的使用extends关键字指定Object为父类 ...

  9. 微信小程序 js创建Object对象

    参考链接: (1)微信小程序开发教程之Object对象 https://www.hishop.com.cn/xiaocx/show_36804.html 一.创建对象 (1)通过函数的形式来创建对象( ...

最新文章

  1. SpringBatch配置数据库
  2. 保姆级教程:Spring Boot 单元测试
  3. Express2.X迁移至3.X注意事项
  4. GeoHash -------寻找附近人
  5. gensim中文处理
  6. ubuntu中mysql怎么退出命令_Ubuntu下MySQL简单操作
  7. Cell子刊主编:文章被编辑拒稿,主要是这4大原因
  8. xxxxxxxxxccccxcc
  9. Kotlin 函数(普通函数)
  10. C# Access 读写数据库
  11. 计算机环模实验报告,误差配套实验报告
  12. redmibook pro 14 arch linux alsamixer 检测不到声卡
  13. 亲测美团打车聚合服务:要做出行服务的天猫?
  14. 小鸟壁纸 删除 卸载 流氓 鲁大师 360 软件 弹窗 后台
  15. SQL语法基础之updata
  16. Linux零基础入门(一)初识Linux
  17. 本周最新文献速递20220320
  18. Java—九九乘法表
  19. Android:高德SDK的基本使用
  20. Dotaer vs Loler

热门文章

  1. Python socket Ftp get put 简单实现
  2. 架构畅想:如果以你所会去进行架构,会到哪一步?
  3. 简单帐表插件开发示例分享
  4. JAVA中的Hashset类
  5. UML:类关系的图例
  6. 驱动开发类文章公告篇
  7. 画风清奇!看看大佬怎么玩Python
  8. 基于Linux下嵌入式网关,基于嵌入式Linux系统的无线网络网关设计
  9. Redis的session管理和Memcached的session管理不同
  10. RabbitMQ Topic交换机(生产者)