Java浅克隆和深克隆深入理解(2)

public class CarCloneTest {
    public static void main(String[] args) {
        Brand brand = new Brand("BMW");
        Car car = new Car(5, brand);
        Car carClone;
        carClone = (Car) car.clone();  //(1)
        //carClone = (Car) car.deepClone(); //(2)
       
        System.out.println("******************************************");
        System.out.println("car "+car);
        System.out.println("carClone "+carClone);
       
        System.out.println("******************************************");
        System.out.println("将car年限改为 7,品牌名称改为Banz");
        brand.setName("Banz");
        car.setYear(7);
       
        System.out.println("******************************************");
        System.out.println("car "+car);
        System.out.println("carClone "+carClone);
    }
}

浅克隆测试,运行(1)代码,得到结果如下:

******************************************
car [year=5, brand=Brand [name=BMW]]
carClone [year=5, brand=Brand [name=BMW]]
******************************************
将car年限改为 7,品牌名称改为Banz
******************************************
car [year=7, brand=Brand [name=Banz]]
carClone [year=5, brand=Brand [name=Banz]]

可见当修改car中brand对象的名称为Banz时,carClone也跟着改变,可见其引用的brand对象为同一个,显然这不是我们想要的,而深克隆就解决了这个问题。

深克隆测试,运行(2)代码,得到结果如下:

******************************************
car [year=5, brand=Brand [name=BMW]]
carClone [year=5, brand=Brand [name=BMW]]
******************************************
将car年限改为 7,品牌名称改为Banz
******************************************
car [year=7, brand=Brand [name=Banz]]
carClone [year=5, brand=Brand [name=BMW]]

三、序列化实现深克隆

序列化对象必须实现Serializable接口,使对象可序列化。

public class Car implements Serializable{
    private static final long serialVersionUID = 7883197573658810857L;
    private int year; //使用年限
    private Brand brand; //品牌
   
    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
    public Brand getBrand() {
        return brand;
    }
    public void setBrand(Brand brand) {
        this.brand = brand;
    }
   
    public Car(int year, Brand brand) {
        this.year = year;
        this.brand = brand;
    }
   
    @Override
    public String toString() {
        return "[year=" + year + ", brand=" + brand + "]";
    }
}
class Brand implements Serializable{
    private static final long serialVersionUID = -6505899377489945908L;
    private String name;

public String getName() {
        return name;
    }

public void setName(String name) {
        this.name = name;
    }
   
    public Brand(String name) {
        this.name = name;
    }

@Override
    public String toString() {
        return "Brand [name=" + name + "]";
    }
}

克隆工具类 CloneUtil:

public final class CloneUtil {
    private CloneUtil() { throw new AssertionError(); }
   
    /**
    * 序列化实现深克隆
    * @param t 泛型对象
    * @return
    */
    @SuppressWarnings("unchecked")
    public static <T> T deepClone(T t) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream objOut;
        ObjectInputStream objIn;
        T tClone = null ;
        try {
            objOut = new ObjectOutputStream(out);
            objOut.writeObject(t);  //将对象以二进制流形式写入
            ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
            objIn = new ObjectInputStream(in);
            tClone = (T)objIn.readObject(); //反序列化读取对象
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return tClone;
    }
}

测试类 CarCloneTest:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/63548b79216deb77b39a1480ebd33c9c.html