Java中的Cloneable接口与深拷贝、浅拷贝
Cloneable接口是一个标记接口,也就是没有任何内容,定义如下:
这里分析一下这个接口的用法,clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类的实例上调用clone方法,否则会抛出CloneNotSupportException。Object中默认的实现是一个浅拷贝,也就是表面拷贝,如果需要实现深层次拷贝的话,必须对类中可变域生成新的实例。
Object提供了一个对象拷贝的默认方法clone方法,但是该方法是有缺陷的,它提供了一种浅拷贝方式,也就是它并不会把对象所有属性全部拷贝一份,而是有选择性的拷贝,拷贝规则如下:
1、基本类型
如果变量是基本类型,则拷贝其值,比如:int、float、long等。
2、String字符串
这个比较特殊,拷贝的是地址,是个引用,但是在修改的时候,它会从字符串池(String Pool)中重新生成新的字符串,原有的字符串对象保持不变,此处可以认为String是个基本类型。
3、对象
如果变量时一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。这在Java中很疯狂,因为它突破了访问权限的定义,一个private修饰的变量,竟然可以被两个实例对象访问。
Cloneable接口如下:如果调用Object的clone方法,没有实现Cloneable接口,则会抛出CloneNotSupportedException
package java.lang; /** * Invoking Object's clone method on an instance that does not implement the
* <code>Cloneable</code> interface results in the exception
* <code>CloneNotSupportedException</code> being thrown.
*
* @author unascribed
* @see java.lang.CloneNotSupportedException
* @see java.lang.Object#clone()
* @since JDK1.0
*/
public interface Cloneable {
}
关于clone方法的浅拷贝的一个demo,可以看出虽然是两个不同的ShallowCopy对象,但是对于他们的非基本数据类型的成员变量是属于同一个引用。因此是浅拷贝
package com.yyrookie.test;
import java.util.Date;
public class ShallowCopy implements Cloneable {
private Date begin;
public Date getBegin(){
return this.begin;
}
public void setBegin(Date d){
this.begin = d;
}
public Object clone(){
Object obj = null;
try{
obj = super.clone();
}catch(CloneNotSupportedException ex){
ex.printStackTrace();
}
return obj;
}
public static void main(String[] args) {
Date date = new Date(10000L);
ShallowCopy copy = new ShallowCopy();
copy.setBegin(date);
ShallowCopy copy2 = (ShallowCopy) copy.clone();
System.out.println(copy.getBegin() + "\n"
+ copy2.getBegin() + "\n" +
(copy == copy2));
date.setTime(100000000L);;
System.out.println(copy.getBegin() + "\n"
+ copy2.getBegin() + "\n" +
(copy == copy2));
}
// Thu Jan 01 08:00:10 CST 1970
// Thu Jan 01 08:00:10 CST 1970
// false
// Fri Jan 02 11:46:40 CST 1970
// Fri Jan 02 11:46:40 CST 1970
// false
}
相比深拷贝,拷贝对象的同时,又进行了对成员对象进行了深拷贝。
package com.yyrookie.test;
import java.util.Date;
public class DeepCopy implements Cloneable{
private Date begin;
public Date getBegin(){
return this.begin;
}
public void setBegin(Date d){
this.begin = d;
}
public Object clone(){
DeepCopy obj = null;
try{
obj = (DeepCopy)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
obj.setBegin((Date)this.getBegin().clone());
return obj;
}
public static void main(String[] args) {
Date date = new Date(10000L);
DeepCopy copy = new DeepCopy();
copy.setBegin(date);
DeepCopy copy2 = (DeepCopy) copy.clone();
System.out.println(copy.getBegin() + "\n"
+ copy2.getBegin() + "\n" +
(copy == copy2));
date.setTime(100000000L);
System.out.println(copy.getBegin() + "\n"
+ copy2.getBegin() + "\n" +
(copy == copy2));
}
// Thu Jan 01 08:00:10 CST 1970
// Thu Jan 01 08:00:10 CST 1970
// false
// Fri Jan 02 11:46:40 CST 1970
// Thu Jan 01 08:00:10 CST 1970
// false
}
Java中的Cloneable接口与深拷贝、浅拷贝的更多相关文章
- Java中的Cloneable接口理解
Cloneable接口是一个标记接口,也就是没有任何内容,定义如下: 这里分析一下这个接口的用法,clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类 ...
- java中的标记接口(标签接口)
Java中的标记接口(Marker Interface),又称标签接口(Tag Interface),具体是不包含任何方法的接口.在Java中很容易找到标记接口的例子,比如JDK中的Serialzab ...
- Java 中的集合接口——List、Set、Map
Java 中的集合接口——List.Set.Map 什么叫集合:集合就是Java API所提供的一系列类的实例,可以用于动态存放多个对象.这跟我们学过的数组差不多,那为什么我们还要学集合,我们看看数组 ...
- 转:二十一、详细解析Java中抽象类和接口的区别
转:二十一.详细解析Java中抽象类和接口的区别 http://blog.csdn.net/liujun13579/article/details/7737670 在Java语言中, abstract ...
- 关于JAVA中抽象类和接口的区别辨析
今天主要整理一下新学习的有关于Java中抽象类和接口的相关知识和个人理解. 1 抽象类 用来描述事物的一般状态和行为,然后在其子类中去实现这些状态和行为.也就是说,抽象类中的方法,需要在子类中进行重写 ...
- Java中的Serializable接口和transient关键字
Java中的Serializable接口和transient关键字 Table of Contents 1. 向memcached中放数据时遇到NotSerializableException异常 2 ...
- 用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑
大家好,又见面了. 今天我们一起聊一聊JAVA中的函数式接口.那我们首先要知道啥是函数式接口.它和JAVA中普通的接口有啥区别?其实函数式接口也是一个Interface类,是一种比较特殊的接口类,这个 ...
- Java中的Serializable接口transient关键字,及字节、字符、对象IO
1.什么是序列化和反序列化Serialization是一种将对象转为为字节流的过程:deserialization是将字节流恢复为对象的过程. 2.什么情况下需要序列化a)当你想把的内存中的对象保存到 ...
- java中的标记接口
在java 中,RandomAccess和Cloneable .Serializable一样,都是标志性接口,不需要任何实现,只是又来表明其实现类具体有某种特质的,实现了Cloneable表明可以拷贝 ...
随机推荐
- WdatePicker.js的使用方法 帮助文档 使用说明(时间控件)*转载
4. 日期范围限制 静态限制 注意:日期格式必须与 realDateFmt 和 realTimeFmt 一致 你可以给通过配置minDate(最小日期),maxDate(最大日期)为静态日期值,来限定 ...
- spark再总结
1.Spark是什么? UCBerkeley AMPlab所开源的类HadoopMapReduce的通用的并行计算框架. dfsSpark基于mapreduce算法实现的分布式计算,拥有HadoopM ...
- 转:CEF嵌入到单文档mfc
1.下载: http://www.magpcss.net/cef_downloads/下载cef binary 1.1364.1123 windows.zip(可能要FQ,百度goagent教程,最好 ...
- linux svn配置hooks
先创建仓库: svnadmin create /data/svn/my.com 再配置权限: #cd /data/svn/my.com/conf/ #vim svnserve.conf 配置 [gen ...
- HDC与CDC相互转换
转自loop_k原文 HDC与CDC相互转换 概念 首先说一下什么是DC(设备描述表):Windows应用程序通过为指定设备(屏幕,打印机等)创建一个设备描述表(Device Context, DC) ...
- 学习日记之抽象工厂模式和Effective C++
抽象工厂模式(Abstract Factory):提供一个创建一系列相关或者相互依赖对象的接口.而无需制定他们详细的类. (1),工厂方法模式是定义一个用于创建对象的接口.让子类决定实例化哪一个类. ...
- bash 文件头尾插入字符
头部插入:sed -i '1i\Insert this line' file.txt 尾部插入:echo "hehe" >> tmp.txt
- "听话"的品格的症状
反思了一下,也许是因为以前比较听话,听大人的话,听老师的话,听长辈的话.听电视剧的话..........哈哈 现在发现,世界是靠自己去认识,去体会的,别人的经验都只能作为参考,绝对不能不加思考的照搬硬 ...
- booth乘法器原理
在微处理器芯片中,乘法器是进行数字信号处理的核心,同一时候也是微处理器中进行数据处理的wd=%E5%85%B3%E9%94%AE%E9%83%A8%E4%BB%B6&hl_tag=textli ...
- Android:图片中叠加文字,支持拖动改变位置
之所以做了这么一个Demo,是由于近期项目中有一个奇葩的需求:用户拍摄照片后,分享到微信的同一时候加入备注,想获取用户在微信的弹出框输入的内容.保存在自己的server上.而其实,这个内容程序是无法获 ...