如何實現對象克隆?


有兩種方式:

1). 實現 Cloneable 接口並重寫 Object 類中的 clone()方法;

2). 實現 Serializable 接口,通過對象的序列化和反序列化實現克隆,可以實現真

正的深度克隆,代碼如下。

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class MyUtil {

private MyUtil() {

throw new AssertionError();

}

@SuppressWarnings("unchecked")

public static <T extends Serializable> T clone(T obj) throws

Exception {

ByteArrayOutputStream bout = new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(bout);

oos.writeObject(obj);

ByteArrayInputStream bin = new

ByteArrayInputStream(bout.toByteArray());

ObjectInputStream ois = new ObjectInputStream(bin);

return (T) ois.readObject();

// 說明:調用 ByteArrayInputStream 或 ByteArrayOutputStream

對象的 close 方法沒有任何意義

// 這兩個基於內存的流只要垃圾回收器清理對象就能夠釋放資源,這

一點不同於對外部資源(如文件流)的釋放

}

}

下面是測試代碼:

import java.io.Serializable;

/**

* 人類

* @author 駱昊

*

*/

class Person implements Serializable {

private static final long serialVersionUID = -9102017020286042305L;

private String name;

// 姓名

private int age;

// 年齡

private Car car;

// 座駕

public Person(String name, int age, Car car) {

this.name = name;

this.age = age;

this.car = car;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public Car getCar() {

return car;

}

public void setCar(Car car) {

this.car = car;

}

@Override

public String toString() {

return "Person [name=" + name + ", age=" + age + ", car=" +

car + "]";

}

}

/**

* 小汽車類

* @author 駱昊

*

*/

class Car implements Serializable {

private static final long serialVersionUID = -5713945027627603702L;

private String brand;

// 品牌

private int maxSpeed;

// 最高時速

public Car(String brand, int maxSpeed) {this.brand = brand;

this.maxSpeed = maxSpeed;

}

public String getBrand() {

return brand;

}

public void setBrand(String brand) {

this.brand = brand;

}

public int getMaxSpeed() {

return maxSpeed;

}

public void setMaxSpeed(int maxSpeed) {

this.maxSpeed = maxSpeed;

}

@Override

public String toString() {

return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed +

"]";

}

}

class CloneTest {

public static void main(String[] args) {

try {

Person p1 = new Person("Hao LUO", 33, new Car("Benz",

300));

Person p2 = MyUtil.clone(p1);

// 深度克隆

p2.getCar().setBrand("BYD");

// 修改克隆的 Person 對象 p2 關聯的汽車對象的品牌屬性

// 原來的 Person 對象 p1 關聯的汽車不會受到任何影響

// 因為在克隆 Person 對象時其關聯的汽車對象也被克隆了

System.out.println(p1);

} catch (Exception e) {

e.printStackTrace();

}

}

}

注意:基於序列化和反序列化實現的克隆不僅僅是深度克隆,更重要的是通過泛

型限定,可以檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,

不是在運行時拋出異常,這種是方案明顯優於使用 Object 類的 clone 方法克隆對

象。讓問題在編譯的時候暴露出來總是好過把問題留到運行時。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM