java Clone
我以前知道java有拷贝,深拷贝和浅拷贝,但是再详细点,说说什么是深拷贝,什么是浅拷贝,就说不出来了,今天正好有时间,就看了看。
这里有3篇文章,分析的都比较全,比较好,但是我实际测试的结果和他们文章中的结果有些出入,大家还是要在自己的机器上跑一下才好,我的测试代码,见下:
package com.java.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class CloneTest1 {
public static void main(String[] args) throws CloneNotSupportedException {
User u1 = new User("xxx");
User u2 = u1;
User u3 = (User) u1.clone();
System.out.println(u1 == u2); // true
System.out.println(u1.equals(u2)); // true
System.out.println(u1 == u3); // false
System.out.println(u1.equals(u3)); // false
System.out.println(u1.hashCode() + " , " + u1.name + " , " + u3.hashCode() + " , "
+ u3.name);
System.out.println("-------------");
Account ac1 = new Account(u1, 2);
Account ac2 = ac1;
Account ac3 = (Account) ac1.clone();
System.out.println(ac1 == ac2); // true
System.out.println(ac1.equals(ac2)); // true
System.out.println(ac1 == ac3); // false
System.out.println(ac1.equals(ac3)); // false
System.out.println(ac1.user == ac3.user); // true ! It's not our
// expected!!!!!
System.out.println(ac1.user.equals(ac3.user)); // true
System.out.println("-------------");
AppInfo src = new AppInfo(new App("Kent"), 8);
AppInfo dist = BeanUtil.cloneTo(src);
System.out.println(src == dist); // false
System.out.println(src.equals(dist)); // true
System.out.println(src.user == dist.user); // false ! Well // done!
System.out.println(src.user.equals(dist.user)); // true
}
static class User implements Cloneable {
String name;
User(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
static class Account implements Cloneable {
User user;
long a;
Account(User u, long b) {
user = u;
a = b;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// Account acc = (Account) super.clone();
// acc.user = (User) acc.user.clone();
// return acc;
return super.clone();
}
}
static class App implements Serializable {
String name;
App(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
static class AppInfo implements Serializable {
App user;
long a;
AppInfo(App u, long b) {
user = u;
a = b;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// Account acc = (Account) super.clone();
// acc.user = (User) acc.user.clone();
// return acc;
return super.clone();
}
}
static class BeanUtil {
@SuppressWarnings("unchecked")
public static <T> T cloneTo(T src) throws RuntimeException {
ByteArrayOutputStream memoryBuffer = new ByteArrayOutputStream();
ObjectOutputStream out = null;
ObjectInputStream in = null;
T dist = null;
try {
out = new ObjectOutputStream(memoryBuffer);
out.writeObject(src);
out.flush();
in = new ObjectInputStream(new ByteArrayInputStream(memoryBuffer.toByteArray()));
dist = (T) in.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (out != null)
try {
out.close();
out = null;
} catch (IOException e) {
throw new RuntimeException(e);
}
if (in != null)
try {
in.close();
in = null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return dist;
}
}
}
补充一下,这里也涉及到 == & equals 的区别,理论上说:== 比较的是两个对象的地址,而equals比较的是两个对象的内容是否相同。但是还要实际测试未准,我一直对这个理解的不够深入。因为我理解的,以及从网上看到的和实际机器上运行的情况总是有差别。所以,我不知道哪个是正确的了。不懂的自行Google吧~
http://kentkwan.iteye.com/blog/739514
http://blog.sina.com.cn/s/blog_6145ed810100uy8b.html