深拷贝、浅拷贝与Cloneable接口
2024-09-07 10:48:33
深拷贝与浅拷贝
浅拷贝
public class Student implements Cloneable{
Integer a;
Integer b;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
String c;
Student child;
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Student s = new Student();
Student s2 = (Student) s.clone();
System.out.println(s == s2);
System.out.println(s.child == s2.child);
}
}
/**********************************************************************/
false
true
由上述代码及运行结果我们可以看出,调用clone方法之后,确实s2是一个新的对象,内存地址已经发生了改变,但s和s2的child属性仍然指向相同的地址,这便是浅拷贝,当然8种基本数据类型是深拷贝,String则是例外。
深拷贝
public class Teacher implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Student implements Cloneable{
Integer a;
Integer b;
public Student(Teacher t) {
this.t = t;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Student s = (Student) super.clone();
s.t = (Teacher)s.t.clone();//彻底深拷贝关键
return s;
}
String c;
Teacher t;
}
public class IntersectionofTwoArraysII {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher t = new Teacher();
Student s = new Student(t);
Student s2 = (Student) s.clone();
System.out.println(s == s2);
System.out.println(s.t == s2.t);
}
}
/**********************************************************************/
false
false
如上代码运行结果所示为深拷贝,想要实现深拷贝,就需要在重写Cloneable接口的clone()方法,并调用属性的clone()方法,因此关联类也要实现Cloneable接口,从而形成拷贝链,实现彻底深拷贝。
实现彻底的深拷贝并不容易,因为它要求涉及的所有类都实现了cloneable接口,但是如StringBuffer由于其没有实现Cloneable接口,想要实现深拷贝效果,则需要做特殊处理从而实现深拷贝的效果。可以在clone方法中实现
sb=new StringBuffer(sb.toString());
Cloneable接口
Cloneable其实就是一个标记接口,只有实现这个接口后,然后在类中重写Object中的clone方法,然后通过类调用clone方法才能克隆成功,如果不实现Cloneable其实就是一个标记接口接口,调用clone方法则会抛出CloneNotSupportedException(克隆不被支持)异常。
如何判断类是否实现了cloneable接口呢?
/**
* Creates and returns a copy of this {@code Object}. The default
* implementation returns a so-called "shallow" copy: It creates a new
* instance of the same class and then copies the field values (including
* object references) from this instance to the new instance. A "deep" copy,
* in contrast, would also recursively clone nested objects. A subclass that
* needs to implement this kind of cloning should call {@code super.clone()}
* to create the new instance and then create deep copies of the nested,
* mutable objects.
*
* @return a copy of this object.
* @throws CloneNotSupportedException
* if this object's class does not implement the {@code
* Cloneable} interface.
*/
protected Object clone() throws CloneNotSupportedException {
if (!(this instanceof Cloneable)) {
throw new CloneNotSupportedException("Class doesn't implement Cloneable");
}
return internalClone((Cloneable) this);
}
/*
* Native helper method for cloning.
*/
private native Object internalClone(Cloneable o);
clone方法首先会判对象是否实现了Cloneable接口,若无则抛出CloneNotSupportedException, 最后会调用internalClone. intervalClone是一个native方法,一般来说native方法的执行效率高于非native方法。
参考资料
最新文章
- python之路二
- August 28th 2016 Week 36th Sunday
- PHP弱类型安全问题的写法和步骤
- Python中一些内建函数及os等模块的用法
- PHP中mysql_affected_rows()和mysql_num_rows()区别
- 1.6.1 什么是 Indexing
- mysql颠覆实战笔记(七)--白话理解事务
- [POJ 3420] Quad Tiling
- Spring MVC Controller配置方式
- apache httpd配置ajp报错:ap_proxy_connect_backend disabling worker for (localhost)
- COJ 0024 N皇后问题
- SqlServer经典函数之数字去零
- nova的wsgi介绍【WIP】
- [LeetCode]题解(python):003-Longest Substring Without Repeating Characters
- ios 修改导航栏返回按钮的图片
- SQL Access Advisor in Oracle Database 10g
- Delphi 三层框架 DataSnap 的服务器端设置
- js知识巩固
- AWS Redshift typical error and potential root cause:
- 中证500等主要指数的市盈率(PE)估值高度
热门文章
- C/C++知识总结 五 复合数据类型 壹(数组、字符串与string、结构)
- 1030 Travel Plan (30分)(dijkstra 具有多种决定因素)
- on duplicate key update 的用法说明(解决批量操作数据,有就更新,没有就新增)mybatis批量操作数据更新和添加
- Redis设计与实现笔记 - hash
- .net core 跨平台开发 微服务架构 基于Nginx反向代理 服务集群负载均衡
- Scratch 第4课满天星
- gdb调试工具常用命令 &;&; kdb
- C语言实现链表(链式存储结构)
- 本地项目推送到Github
- 如何提高你使用windows的逼格(windows用成Linux的赶脚)