java clone 源码_Java Clone方法之懒人实现

在Java的Object类中定义了(protected)clone()方法,如果自己的类需要clone方法的话需要实现Cloneable接口,并重写clone()方法和将方法访问级别改为(public)。但是如果自己的类如果属性比较多,重写clone方法还是会花去不少时间,更重要的是以后增加或者删除属性的时候也要相应修改clone方法,总的来说还是比较麻烦的。

这里如果对性能不太计较的话,其实可以有一个简单快速的方法实现clone方法,就是使用Java语言的序列化功能来实现clone方法,如下:

以下是几个测试的Bean类

import java.io.Serializable;

public class A implements Serializable {

private static final long serialVersionUID = 1L;

private String name;

private B b;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public B getB() {

return b;

}

public void setB(B b) {

this.b = b;

}

@Override

public Object clone() {

return CloneUtil.clone(this);

}

}

import java.io.Serializable;

public class B implements Serializable {

private static final long serialVersionUID = 1L;

private String name;

private C c;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public C getC() {

return c;

}

public void setC(C c) {

this.c = c;

}

@Override

public Object clone() {

return CloneUtil.clone(this);

}

}

import java.io.Serializable;

public class C implements Serializable, Cloneable {

private static final long serialVersionUID = 1L;

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public Object clone() {

return CloneUtil.clone(this);

}

}

Clone工具类,这个类负责通过序列化和反序列化做到对一个对象的clone

import java.io.*;

public class CloneUtil {

public static Object clone(Object obj) {

Object anotherObj = null;

byte[] bytes;

ByteArrayOutputStream baos = new ByteArrayOutputStream();

ObjectOutputStream oos = null;

try {

oos = new ObjectOutputStream(baos);

oos.writeObject(obj);

bytes = baos.toByteArray();

} catch(IOException ex) {

throw new RuntimeException(ex.getMessage(), ex);

} finally {

if (oos != null) {

try {

oos.close();

} catch (IOException e) {

// ignore me

}

}

}

ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

ObjectInputStream ois = null;

try {

ois = new ObjectInputStream(bais);

anotherObj = ois.readObject();

} catch(IOException ex) {

throw new RuntimeException(ex.getMessage(), ex);

} catch(ClassNotFoundException ex) {

throw new RuntimeException(ex.getMessage(), ex);

} finally {

if (ois != null) {

try {

ois.close();

} catch (IOException e) {

// ignore me

}

}

}

return anotherObj;

}

}

测试类

public class Test {

public static void main(String[] args) throws Exception {

A a = new A();

B b = new B();

C c = new C();

c.setName("ccc");

b.setName("bbb");

b.setC(c);

a.setName("aaa");

a.setB(b);

System.out.println("a: " + a);

System.out.println("a: " + a.getName());

System.out.println("a: " + a.getB().getName());

System.out.println("a: " + a.getB().getC().getName());

A anotherA = (A)a.clone();

System.out.println("anotherA: " + anotherA);

System.out.println("anotherA: " + anotherA.getName());

System.out.println("anotherA: " + anotherA.getB().getName());

System.out.println("anotherA: " + anotherA.getB().getC().getName());

System.out.println("=== change properties of a ===");

a.setName("aaaaa");

a.getB().setName("bbbbb");

a.getB().getC().setName("ccccc");

System.out.println("a: " + a);

System.out.println("a: " + a.getName());

System.out.println("a: " + a.getB().getName());

System.out.println("a: " + a.getB().getC().getName());

System.out.println("anotherA: " + anotherA);

System.out.println("anotherA: " + anotherA.getName());

System.out.println("anotherA: " + anotherA.getB().getName());

System.out.println("anotherA: " + anotherA.getB().getC().getName());

System.out.println("=== change properties of anotherA ===");

anotherA.setName("aaaa");

anotherA.getB().setName("bbbb");

anotherA.getB().getC().setName("cccc");

System.out.println("a: " + a);

System.out.println("a: " + a.getName());

System.out.println("a: " + a.getB().getName());

System.out.println("a: " + a.getB().getC().getName());

System.out.println("anotherA: " + anotherA);

System.out.println("anotherA: " + anotherA.getName());

System.out.println("anotherA: " + anotherA.getB().getName());

System.out.println("anotherA: " + anotherA.getB().getC().getName());

}

}

运行测试类可以看到结果。这里通过代码可以看出这种实现还是有一些限制的:

1. 自己的bean必须实现Serializable接口;

2. 由于这种实现使用了序列化,所以性能不是很好,所以如果对象太多,不建议使用;

3. 由于在序列化的过程中没有将对象序列化到文件中,而是保留在了内存数组中,所以如果对象太大的话,会造成比较大的内存使用,需要注意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值