zoukankan      html  css  js  c++  java
  • 如何实现对象克隆?

    有两种方式:

    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 方法克隆对

    象。让问题在编译的时候暴露出来总是好过把问题留到运行时。

  • 相关阅读:
    73. Set Matrix Zeroes
    289. Game of Live
    212. Word Search II
    79. Word Search
    142. Linked List Cycle II
    141. Linked List Cycle
    287. Find the Duplicate Number
    260. Single Number III
    137. Single Number II
    Oracle EBS中有关Form的触发器的执行顺序
  • 原文地址:https://www.cnblogs.com/programb/p/13021329.html
Copyright © 2011-2022 走看看