博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Object对象具体解释(二)之clone
阅读量:6439 次
发布时间:2019-06-23

本文共 7076 字,大约阅读时间需要 23 分钟。

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 Cloneable 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. * 

* Invoking Object's clone method on an instance that does not implement the * Cloneable interface results in the exception * CloneNotSupportedException being thrown. *

* By convention, classes that implement this interface should override * Object.clone (which is protected) with a public method. * See {@link java.lang.Object#clone()} for details on overriding this * method. *

* Note that this interface does not contain the clone 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:     * 
*
     * x.clone() != x
* will be true, and that the expression: *
*
     * x.clone().getClass() == x.getClass()
* will be {@code true}, but these are not absolute requirements. * While it is typically the case that: *
*
     * x.clone().equals(x)
* will be {@code true}, this is not an absolute requirement. *

* 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()}. *

* 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. *

* 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. *

* 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}. */ @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return 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 stub        People 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

转载地址:http://jlzwo.baihongyu.com/

你可能感兴趣的文章
沃尔玛建立自家的人工智能网络,抗衡竞争对手亚马逊
查看>>
Mysql备份与还原及优化方法
查看>>
linux常用命令和选项
查看>>
sed 学习笔记(未完成)
查看>>
Eclipse保存验证JS缓慢
查看>>
2017 JMP Discovery Summit China圆满落幕
查看>>
9 Easy Steps for Successful Data Migration
查看>>
人工智能,不止于技术的革命--WOT2017全球创新技术峰会开幕
查看>>
mysql 在大型应用中的架构演变
查看>>
ibm系列文章 --> Windows 到 Linux 之旅
查看>>
全备份失败后,如何手工清除exchange日志文件,附微软KB
查看>>
java如何连接mysq之源码l讲解
查看>>
企业运维笔试考题(1)
查看>>
Mysql修改存储过程相关权限问题
查看>>
4.2权限管理
查看>>
彻底理解ThreadLocal
查看>>
Node.js~ioredis处理耗时请求时连接数瀑增
查看>>
企业如何走出自己的CRM非常之道?
查看>>
整合看点: DellEMC的HCI市场如何来看?
查看>>
联合国隐私监督机构:大规模信息监控并非行之有效
查看>>