Java对象深复制的3种方式对比
2017-12-07 本文已影响0人
hzhqk
关于对象的深复制三种方式:
1、new Instance,即自己new对象一一赋值属性,写起来繁琐;
2、继承Cloneable方式,比较推荐,原生&快速;
3、序列化&反序列化方式(实现Serializable或Externalizable),耗时但是实现简易,功能强大。
import java.io.*;
/**
* Created by hqk2015@foxmail.com on 2017/12/07.
*/
public class Copy implements Cloneable,Serializable {
private String str;
private Obj obj;
public Copy() {
}
private Copy(Obj obj) throws CloneNotSupportedException {
this.obj = (Obj) obj.clone();
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public Obj getObj() {
return obj;
}
public void setObj(Obj obj) {
this.obj = obj;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Copy copy = new Copy(this.obj);
copy.setStr(this.str);
return copy;
}
public Object serializeClone() throws IOException, ClassNotFoundException {
// 将对象写到流里
OutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来
InputStream bi = new ByteArrayInputStream(((ByteArrayOutputStream) bo).toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
//close stream
return (oi.readObject());
}
public Copy newClone() {
Copy copy = new Copy();
copy.setObj(this.obj.newClone());
copy.setStr(this.str);
return copy;
}
public static void main(String[] args) throws Exception {
Copy origin = new Copy();
origin.setStr("str");
origin.setObj(new Obj("field:obj"));
int loop = 10000;
//Cloneable方式
long start = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
origin.clone();
}
long end = System.currentTimeMillis();
long test1 = end - start;
//序列化&反序列化方式
start = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
origin.serializeClone();
}
end = System.currentTimeMillis();
long test2 = end - start;
//new Instance实例属性复制方式
start = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
// BeanUtils.cloneBean(origin);
origin.newClone();
}
end = System.currentTimeMillis();
long test3 = end - start;
System.out.println("Cloneable方式: " + test1
+ "ms\n序列化方式: " + test2
+ "ms\nnew Instance方式: " + test3 + "ms");
}
}
class Obj implements Cloneable,Serializable{
private String str;
public Obj() {
}
public Obj(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Obj newClone() {
Obj obj = new Obj();
obj.setStr(this.str);
return obj;
}
}
用IntelliJ IDEA多次测试,总体来说,耗时: 序列化 > new Instance > Cloneable
以下是10批次(每批次10000次执行)运行结果:
Cloneable方式 | 序列化方式 | new Instance方式
———————————————|————————————|——————————————————————————————
7 | 1457 | 20
7 | 1627 | 5
7 | 1469 | 5
7 | 1584 | 74
13 | 1478 | 6
7 | 1411 | 7
6 | 1530 | 8
7 | 1494 | 17
7 | 1528 | 5
6 | 1486 | 44
————————————————————————————————————————————————————————————
平均(ms):7.4 | 1506.4 | 19.1