网站首页 > java教程 正文
Java 语言设计
Java语言设计为:一个类的对象如果想要被克隆,这个类必须实现Cloneable接口。我们先看Cloneable接口:
- 一个类实现Cloneable接口,才可以合法调用Object类的clone方法。注意:Cloneable接口是空的,并不包含clone方法。clone方法是在Object类中被声明为protected。如果一个类没有实现Cloneable接口而调用clone方法,会抛出CloneNotSupportedException异常。
- 按照惯例实现Cloneable接口的类都要重写Object的clone方法。
既然clone方法再Object中,我们进入Object类看看clone方法的声明:
clone方法上面的声明太长了就不一块截下来了,可以自己进去看看。
clone方法用于创建此对象的拷贝。拷贝的确切含义可能取决于对象具体的类。一般意图是对于任何对象:
x.clone() == x; 返回false x.clone().getClass() == x.getClass(); 返回true
虽然通常情况下
x.clone().equals(x); 返回true
但这些并不是绝对的要求。
所有实现了Cloneable接口的类都应该用一个共有的方法覆盖Object的clone方法,并且在该clone方法内部应该先调用super.clone()方法,然后再修正需要调整的域。因为这样才可以递归调用到Object的clone方法,从而创建出正确的克隆。否则如果我们直接再clone方法里通过构造器创建对象,就可能得不到预期的类。
所有数组都被认为是实现了Cloneable接口,并且数组类型 T [] 的clone方法的返回类型是 T [],其中T可以是任何引用类型或原始类型。
深拷贝和浅拷贝
先看一段代码:
上面这个代码输出结果为:
Person@4554617c/Person@4554617c/Person@74a14482
可以看大,p1和p2输出相同,p3输出不同。下面来解释一下:
看过Java虚拟机的都知道,Java运行时数据区的概念。在这个例子里面,p1、p2、p3三个变量会在栈中创建,new出来的剑桥大学张三这个Person对象在Java堆中创建。代码中,p1和p2指向的是Java堆中的同一个对象,所以输出相同。但p1.clone()语句是在Java堆中克隆一个新的张三,并被p3引用,这是两个对象,所以p3输出不同于p1和p2。
知道了这个概念,那么什么是深拷贝什么是浅拷贝?
如果我们把上面的输出语句换成:
System.out.println(p1.getSchool()+"/"+p2.getSchool()+"/"+p3.getSchool());
那么看一下输出:
School@6bc168e5/School@6bc168e5/School@6bc168e5
p1、p2、p3输出的school对象信息都一样。这是因为Java执行的是浅拷贝。虽然我克隆了Person,但Person里面的School并没有克隆,仅仅是将拷贝对象里面的school引用指向了原new出来的Person对象创建的School。也就是默认克隆仅仅克隆本对象,本对象内部引用的其他对象,仅仅是传递引用,并没有为它们克隆新的实例。那么Java如何进行深拷贝呢?我只需要为School类添加clone方法并且修改Person类的clone方法即可,主函数中p1、p2、p3赋值关系不变:
输出结果为:
School@4554617c/School@4554617c/School@74a14482
可以看出,p3的School也进行了拷贝。
如果School类中也组合了其他对象呢?如果需要深拷贝,School中组合的类也应该重写clone方法,并且在School类的clone方法中调用。也就是说这是一个clone调用链。如果想要进行完全深拷贝,必须保证这个clone调用链的完整。
其他文章:
猜你喜欢
- 2024-10-19 Python 中赋值、浅拷贝、深拷贝的区别是什么?
- 2024-10-19 Java 对象拷贝原理剖析(java 对象拷贝原理剖析)
- 2024-10-19 认识Object类和深浅拷贝!(阐述object.assign的用法,深拷贝与浅拷贝的区别?)
- 2024-10-19 三面“有赞”Java岗斩获offer:Spring+JVM+并发锁+分布式+算法
- 2024-10-19 谈谈 Java 开发中的对象拷贝(java对象拷贝工具类)
- 2024-10-19 深入浅出Java中的clone克隆方法,写得也太棒了
- 2024-10-19 深拷贝和浅拷贝之list、dataframe
- 2024-10-19 对象拷贝java 浅谈(java对象的拷贝)
- 2024-10-19 Java的Object十二个常用方法,你用过几个?
- 2024-10-19 面试官问:什么是浅拷贝和深拷贝?(浅拷贝与深拷贝区别)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)