cloneable接口:
实现此接口的类——可被推断java.lang.object
的clone()方法可以被合法调用-以实现类实例:属性到属性的拷贝。
如果一个类未实现cloneable接口,那么调用clone()方法时,会抛出clonenotsupportedexception异常。
通常,实现了cloneable接口的子类,应当以public访问权限重写clone()方法(尽管java.object类中的clone方法是protected类型的)
应当认识到:cloneable接口没有包含clone()方法,因此,如果仅仅是implements了cloneable接口,那么也是无法正常克隆对象的
[原因:即使是反射性地调用了克隆方法,也不能保证它一定会成功]——个人理解就是:是否重写clone()方法、或者“浅拷贝与深拷贝”问题的存在所导致的。
class pet implements cloneable{ //properties private string name; public void tname(string name) { this.name = name; } public string getname() { return name; } public pet() { } public pet(string name) { this.name = name; } @override public string tostring() { return "pet{" + "name='" + name + '\'' + 笔记本有杂音 '}'; } @override public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return fal; pet pet = (pet) o; return objects.equals(name, pet.name); } @override public int hashcode() { return objects.hash(name); }// @override// public pet clone() {// try {// return (pet)super.clone();// } catch (clonenotsupportedexception e) {// e.printstacktrace();// }// return null;// }}
注意到:pet类实现了cloneable接口,但是没有重写clone()方法(显然:此时pet类不具备对象克隆的能力)。
class pet implements cloneable{ //properties private string name; public void tname(string name) { this.name = name; } public string getname() { return name; } public pet() { } public pet(string name) { this.name = name; } @override public string tostring() { return "pet{" + "name='" + name + '\'' + '}'; } @override public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return fal; pet pet = (pet) o; return objects.equals(name, pet.name); } @override public int hashcode() { return objects.hash(name); }// @override// public pet clone() {// try {// return (pet)super.clone();// } catch (clonenotsupportedexception e) {// e.printstacktrace();// }// return null;// }}
注意到:person类实现了cloneable接口,也重写clone()方法。那么,是否person类就具备了对象克隆的能力呢?(由于浅拷贝问题的存在,认为这种对象克隆能力是不完整的、有缺陷的)。
class pet implements cloneable{ //properties private string name; publi散步教案一等奖c void tname(string name) { this.name = name; } public string getname() { return name; } public pet() { } public pet(string name) { this.name = name; } @override public string tostring() { return "pet{" + "name='" + name + '\'' + '}'; } @override public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return fal; pet pet = (pet) o; return obje民办中学cts.equals(name, pet.name); } @override public int hashcode() { return objects.hash(name); }// @override// public pet clone() {// try {// return (pet)super.clone();// } catch (clonenotsupportedexception e) {// e.p择天记 电视剧rintstacktrace();// }// return null;// }}
为什么说:此时person类的对象克隆能力是不完整的、有缺陷的?因为此时,在通过person对象调用clone()方法,克隆对象时,其成员属性pet(pet类的对象)值的克隆,仅仅是对堆区内存地址的简单拷贝。
即:说白了,person对象和克隆出来的对象,其pet属性值共享同一块堆区内存。——问题显而易见:当对克隆出来的对象的pet属性进行t操作时,显然会影响到原始person对象的pet属性值。
代码演示如下:
//methods public static void main(string[] args) throws clonenotsupportedexception { testperson(); } public static void testperson() throws clonenotsupportedexception { person p=new person("张三",14,new pet("小黑")); system.out.println(p); person clone = (person)p.clone(); system.out.println(clone); system.out.println(p.equals(clone)); system.out.println(p.getpet()==clone.getpet()); system.out.println("************"); clone.tage(15); system.out.println(p); system.out.println(clone); s青年委员ystem.out.println(p.equals(clone)); system.out.println("************"); clone.getpet().tname("小黄"); system.out.println(p); system.out.println(clone); system.out.println(p.equals(clone)); system.out.println(p.getpet()==clone.getpet()); }
那么,如何实现深拷贝呢?关键就在上述案例中,被注释的几行代码中。
测试代码不变,再次运行:
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注www.887551.com的更多内容!
本文发布于:2023-04-06 04:33:49,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/b300b805a58dfd22ca58f7cd5ee23c8a.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Java Cloneable接口的深拷贝与浅拷贝详解.doc
本文 PDF 下载地址:Java Cloneable接口的深拷贝与浅拷贝详解.pdf
留言与评论(共有 0 条评论) |