Object对象具体解释(二)之clone
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相关推荐
- Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、
1:Scala之函数式编程学习笔记: 1:Scala函数式编程学习:1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法:class User {private v ...
- php object 对象不存在。增加对象_PHP开发自己的框架,这些知识点不能错过
一.PHP常用的四种数据结构 简介:spl是php的一个标准库. <?php//spl(php标准库)数据结构/*** 栈(先进后出)*/ $stack = new SplStack(); $s ...
- OpenGL ES 名词解释(二)
目录 一.前言 二.坐标系 1.屏幕坐标系 2.纹理坐标系 3.顶点坐标系 4.图像坐标系 三.混合 四.变换矩阵 1.平移 2.旋转 3.缩放 4.矩阵组合顺序 五.投影矩阵 1.正交投影 2.透视 ...
- JavaScript:对Object对象的一些常用操作总结
JavaScript对Object对象的一些常用操作总结. 一.Object.assign() 1.可以用作对象的复制 var obj = { a: 1 }; var copy = Object.as ...
- linq结果转换object_【JavaScript 教程】标准库—Object 对象
作者 | 阮一峰 1.概述 JavaScript 原生提供Object对象(注意起首的O是大写),本章介绍该对象原生的各种方法. JavaScript 的所有其他对象都继承自Object对象,即那些对 ...
- localStorage、sessionStorage本地存取Object 对象 - 代码篇
文章目录 localStorage.sessionStorage本地存取Object 对象 - 代码篇 打印截图: 一. localStorage 实例: 1.1. 重要代码 · 片段如下: 二.se ...
- 【Java】Java 的Object对象你真的懂了吗
1.概述 原文:https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247484210&idx=1&sn=9d40e2 ...
- 第三周阶段性小结——Object对象、String类、StringBuffer、StringBuilder、System、Runtime、Date...
一.Object对象 1.object 类的常用方法: Object类是所有类的父类,java中所有的类都直接或间接地继承自Object类,即使没有显示的使用extends关键字指定Object为父类 ...
- 微信小程序 js创建Object对象
参考链接: (1)微信小程序开发教程之Object对象 https://www.hishop.com.cn/xiaocx/show_36804.html 一.创建对象 (1)通过函数的形式来创建对象( ...
最新文章
- SpringBatch配置数据库
- 保姆级教程:Spring Boot 单元测试
- Express2.X迁移至3.X注意事项
- GeoHash -------寻找附近人
- gensim中文处理
- ubuntu中mysql怎么退出命令_Ubuntu下MySQL简单操作
- Cell子刊主编:文章被编辑拒稿,主要是这4大原因
- xxxxxxxxxccccxcc
- Kotlin 函数(普通函数)
- C# Access 读写数据库
- 计算机环模实验报告,误差配套实验报告
- redmibook pro 14 arch linux alsamixer 检测不到声卡
- 亲测美团打车聚合服务:要做出行服务的天猫?
- 小鸟壁纸 删除 卸载 流氓 鲁大师 360 软件 弹窗 后台
- SQL语法基础之updata
- Linux零基础入门(一)初识Linux
- 本周最新文献速递20220320
- Java—九九乘法表
- Android:高德SDK的基本使用
- Dotaer vs Loler