博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Object的clone()方法的使用
阅读量:4092 次
发布时间:2019-05-25

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

Object类是所有类的父类,所以它们都继承了Object类中的clone()方法,下面尝试使用下clone()。

一、

测试代码

class MyObject {}   // 定义一个空类,Object类的子类public class CloneTest {  		// Object类的子类	public static void main(String[] args) {		Object obj = new Object();		Object obj1 = obj.clone();				MyObject myObj = new MyObject();		MyObject myObj1 = myObj.clone();     // 错误: 不兼容的类型: Object无法转换为MyObject				CloneTest cloneTest = new CloneTest();		CloneTest cloneTest1 = cloneTest.clone(); //错误: 不兼容的类型: Object无法转换为MyObject				System.out.println("obj: "+obj+"  obj1: "+obj1);		System.out.println("myObj: "+myObj+"  myObj1: "+myObj1);		System.out.println("cloneTet: "+cloneTest+"  cloneTest1: "+cloneTest1);	}}

编译结果如下:

将后两行代码进行修改为

MyObject myObj = new MyObject();//MyObject myObj1 = myObj.clone();     // 错误: 不兼容的类型: Object无法转换为MyObjectObject myObj1 = myObj.clone();		CloneTest cloneTest = new CloneTest();//CloneTest cloneTest1 = cloneTest.clone(); //错误: 不兼容的类型: Object无法转换为MyObjectObject cloneTest1 = cloneTest.clone();

后面的两个错误就没了

结果分析

在上面的代码中,主类CloneTest、空类MyObject都是Object类的子类,都继承了Object的clone()方法

1、cloneTest.clone()正常执行,而obj.clone()、myObj.clone()则不可见,说明:

子类CloneTest的对象可以访问自己类型的clone()方法, 却不能访问其父类Object、另一个子类myObj的clone()

也就是说,

不能在一个子类中访问另一个子类的对象的protected方法,尽管这两个子类继承自同一个父类;此外,子类不能访问父类的对象的protected方法,要通过自己类型的对象才能访问

即,只能通过自身实例(自身的引用)访问,不能通过父类实例(父类的引用)、其他子类实例(除非是该子类有重写clone()方法)

2、子类使用继承自父类的clone()方法时,返回的对象仍然是父类类型的对象

二、

测试代码2

class MyObject {	protected Object clone() throws CloneNotSupportedException {		return super.clone();	}}public class CloneTest {  			public static void main(String[] args) throws CloneNotSupportedException {				MyObject myObj = new MyObject();		Object myObj1 = myObj.clone();				CloneTest cloneTest = new CloneTest();		Object cloneTest1 = cloneTest.clone();				System.out.println("myObj: "+myObj+"  myObj1: "+myObj1);		System.out.println("cloneTet: "+cloneTest+"  cloneTest1: "+cloneTest1);	}}

在MyObject类中重写clone()方法,覆盖掉继承自父类的clone()方法,则编译通过,不再有因为protected引起的不可见问题

这时,子类CloneTest可以访问另一个子类MyObject的一个对象的clone()方法。

这时因为,在MyObject类中覆盖clone()方法时,MyObject类和CloneTest类在同一个包下,所以此protected方法对CloneTest类可见。

注意:main方法、重写的clone方法需要throws CloneNotSupportedException,否则编译时会出现下面的错误

但是,在这里虽然编译成功,当我们运行程序时依然会出错

原因分析:

查看Object的源码及文档,发现有这么一句话

The class Object does not itself implement the interface Cloneable, so calling the clone method on an object whose class is Object will result in throwing an exception at run time.

即,Object类中的clone()没有实现Cloneable接口,运行时就会抛出CloneNotSupportedException

而我们的子类MyObject在重写clone()时,也没有实现该接口,所以也会抛出异常

三、实现Cloneable接口

class MyObject implements Cloneable {	protected Object clone() throws CloneNotSupportedException {		return super.clone();	}}public class CloneTest implements Cloneable {  			public static void main(String[] args) throws CloneNotSupportedException {			MyObject myObj = new MyObject();		Object myObj1 = myObj.clone();				CloneTest cloneTest = new CloneTest();		Object cloneTest1 = cloneTest.clone();		System.out.println("myObj: "+myObj+"  myObj1: "+myObj1);		System.out.println("cloneTet: "+cloneTest+"  cloneTest1: "+cloneTest1);		}}

在两个类的定义时写上implements Cloneable,再次编译、运行,这时运行就不会抛出CloneableNotSupportedException了

此外,可以发现

(1)调用clone()返回的对象是一个独立的副本,两个对象地址不同,属性相同。

(2)当我们直接输出两个对象时,尽管原对象的引用是子类类型、副本对象的引用是Object父类类型,输出结果显示对象是子类类型。也就是说,父类类型、子类类型的引用,都可以指向子类类型的对象。

(3)前面看到,clone()返回的对象依然是Object类型,因此,我们只需做强制转换,就可以转化成想要的类型了

MyObject myObj = new MyObject();//MyObject myObj1 = myObj.clone();          //  错误: 不兼容的类型: Object无法转换为MyObject//Object myObj1 = myObj.clone();MyObject myObj1 = (MyObject)myObj.clone();		CloneTest cloneTest = new CloneTest();//CloneTest cloneTest1 = cloneTest.clone(); //  错误: 不兼容的类型: Object无法转换为MyObject//Object cloneTest1 = cloneTest.clone();CloneTest cloneTest1 = (CloneTest)cloneTest.clone();

四、clone的另一种重写方式

/*class MyObject implements Cloneable {	protected Object clone() throws CloneNotSupportedException {		return super.clone();	}}*/class MyObject implements Cloneable {    public Object clone() {        MyObject mo = null;        try {            mo = (MyObject)super.clone();        } catch(CloneNotSupportedException e) {            e.printStackTrace();        }        return mo;    }}

 

你可能感兴趣的文章
卧槽!为鼓励民众居家隔离,国外这些计算机学习资源将免费对外开放!
查看>>
Eclipse Theia 1.0 发布,这才是 VS Code 真正的开源替代方案?!
查看>>
堪称开挂!印度裔 00 后 7 岁教人编程,12 岁成 IBM 荣誉顾问,还出过书!
查看>>
为什么魂斗罗只有 128KB 却可以实现那么长的剧情?
查看>>
全球呼吸机告急!医疗科技巨头美敦力 "开源" 设计图和源代码!
查看>>
哇!动辄上千台服务器,到底在干嘛?
查看>>
霸榜 GitHub:去你丫的算法!
查看>>
卧槽!MIT 正式开放 AI 学习资源网,连小孩都能学!
查看>>
前女友让我撸个植物大战僵尸,我一怒之下把代码开源了...
查看>>
卧槽!长达 5000 页的 Java 中文必备手册正式开放下载!
查看>>
不吹不黑!逛 GitHub 没看过这 10 个开源项目,绝对血亏...
查看>>
这才是你需要的 C 语言、C++ 学习路线!
查看>>
IntelliJ IDEA 2020.1 稳定版正式发布!
查看>>
PyCharm 2020.1 稳定版正式发布!
查看>>
苹果新系统遭吐槽!SSH 默认规则被破坏,程序员无法登录 Web 服务器...
查看>>
卧槽!小姐姐用动画图解 Git 命令,这也太秀了吧?!
查看>>
厉害了!Python 编辑器界的神器 Jupyter ,推出官方可视化 Debug 工具!
查看>>
你的银行账户信息,可能正被人拿到暗网上公开售卖!
查看>>
太赞啦!GitHub 重磅宣布,私有仓库将对外免费开放,不限人数!
查看>>
我用 Python 分析了 “青你 2” 漂亮小姐姐的颜值,结果真香!
查看>>