java的对象克隆
来源:互联网 发布:ubuntu 邮件 编辑:程序博客网 时间:2024/06/07 11:12
对象的拷贝详解:推荐一片不错的博文:http://www.cnblogs.com/plokmju/p/7357205.html
首先需要明白,浅拷贝和深拷贝都是针对一个已有对象的操作。那先来看看浅拷贝和深拷贝的概念。
在 Java 中,除了基本数据类型(元类型)之外,还存在 类的实例对象 这个引用数据类型。而一般使用 『 = 』号做赋值操作的时候。对于基本数据类型,实际上是拷贝的它的值,但是对于对象而言,其实赋值的只是这个对象的引用,将原对象的引用传递过去,他们实际上还是指向的同一个对象。
而浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。
所以到现在,就应该了解了,所谓的浅拷贝和深拷贝,只是在拷贝对象的时候,对 类的实例对象 这种引用数据类型的不同操作而已。
总结来说:
1、浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
2、深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
既然已经了解了对 clone() 方法,只能对当前对象进行浅拷贝,引用类型依然是在传递引用。
那么,如何进行一个深拷贝呢?
比较常用的方案有两种:
1.实现Cloneable接口,重写clone()方法。public class ObjClone1 implements Cloneable {
// 通过clone()实现拷贝
public String name;
public int age;
public ObjChild chd;
// 重写Object 的clone()
@Override
public Object clone() {
ObjClone1 objClone1;
try {
objClone1 = (ObjClone1) super.clone();
objClone1.chd = (ObjChild) this.chd.clone();
return objClone1;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws Exception {
ObjClone1 objcA = new ObjClone1();
objcA.name = "pdj";
objcA.age = 18;
objcA.chd = new ObjChild();
objcA.chd.acct = "seniro";
objcA.chd.no = 123;
ObjClone1 objcB = (ObjClone1) objcA.clone();
System.out.println("objcA==objcB:" + (objcA == objcB));
System.out.println("objcA equals objcB:" + (objcA.equals(objcB)));
System.out.println(objcA.hashCode());
System.out.println(objcB.hashCode());
System.out.println(objcA.name);
System.out.println(objcB.name);
System.out.println(objcA.chd == objcB.chd);
System.out.println(objcA.chd.hashCode());
System.out.println(objcB.chd.hashCode());
}
}
class ObjChild implements Cloneable {
public String acct;
public int no;
@Override
public Object clone(){
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
2.序列化方式。
public class ObjClone2 implements Serializable {
private static final long serialVersionUID = 1L;
public String name;
public int age;
public static void main(String[] args) {
ObjClone2 objA = new ObjClone2();
ObjClone2 objC = new ObjClone2();
objA.name = "pdj";
objA.age = 18;
ObjClone2 objB = clone2(objA);
System.out.println(objA == objB);
System.out.println(objA == objC);
System.out.println("33" + objA.equals(objC));
System.out.println(objA.name);
System.out.println(objA.age);
System.out.println(objB.name);
System.out.println(objB.age);
System.out.println("=============================");
ObjClone2 objB2 = clone1(objA);
System.out.println(objA == objB2);
System.out.println(objA == objC);
System.out.println("33" + objA.equals(objC));
System.out.println(objA.name);
System.out.println(objA.age);
System.out.println(objB2.name);
System.out.println(objB2.age);
}
// 通过序列化方式,在内存中通过字节流的拷贝来实现把母对象写到一个字节流中,再从字节流中将其读出来,实现深度拷贝
public static <T extends Serializable> T clone1(T obj) {
// 拷贝产生的对象
T clonedObj = null;
try {
// 读取对象字节数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.close();
// 分配内存空间,写入原始对象,生成新对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
// 返回新对象,并做类型转换
clonedObj = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return clonedObj;
}
// 通过apache.common.lang包中的SerializationUtils.clone()工具类实现深度序列化,简单方便
public static <T extends Serializable> T clone2(T obj) {
// 拷贝产生的对象
T clonedObj = null;
clonedObj = (T) SerializationUtils.clone(obj);
return clonedObj;
}
- java对象的克隆
- java对象的克隆
- java对象的克隆
- java 对象的克隆
- JAVA对象的克隆
- Java对象的克隆
- JAVA对象的克隆
- java,对象的克隆
- java的对象克隆
- java-对象的克隆
- java的对象克隆
- java 实现对象的克隆
- Java中对象的克隆
- [面试] Java 对象的克隆
- JAVA对象的深度克隆
- JAVA对象的深度克隆
- java中对象的克隆
- Java(对象的深克隆和浅克隆)
- Spring MVC 4.2 增加 CORS 支持
- HDFS、YARN、MapReduce原理--读书笔记
- 软件级负载均衡器(LVS/HAProxy/Nginx)的特点简介和对比
- 如何简单快速查看.Net Framework版本
- 格式化输出width,fill
- java的对象克隆
- Home_W的超级数学题(第k个和m互素的数
- CC2530下ZigBee协议栈中添加BH1750数字光照传感器
- (一)线段树入门--补充与其他模板
- 关于typedef和define的两个错误用法
- 二叉树递归与非递归层次遍历
- WebStorm使用教程
- lua 二进制字节与int相互转换
- 2017百度之星初赛(A)1001 小C的倍数问题(求因子数)