码迷,mamicode.com
首页 > 其他好文 > 详细

克隆对象

时间:2018-04-21 14:30:00      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:out   com   hand   修饰符   leo   继承   student   示例   ext   

1. 为什么要实现克隆

克隆是为了复制一个对象,protected native Object clone() throws CloneNotSupportedException;是native方法,比在java代码中一个个复制对象的属性要简洁并且==速度快==。

克隆对象一般应该实现三个语义:

  1. x.clone() != x will be true保证克隆对象将有单独的内存地址分配。
  2. x.clone().getClass() == x.getClass() will be true,非强制性,原始和克隆的对象应该具有相同的类类型,但它不是强制性的。
  3. x.clone().equals(x),非强制性,原始和克隆的对象应该是平等的equals()方法使用,但它不是强制性的。

克隆分为两种:ShallowClone浅克隆和DeepClone深度克隆,深度克隆支持引用类型的成员变量的复制。

2. 如何实现克隆

浅克隆的一般步骤是

  1. 被克隆的对象类或者其父类实现了Cloneable接口;
  2. 覆盖clone()方法,访问修饰符设为==public==。方法中调用super.clone()方法得到需要的复制对象;
  3. 这种方法克隆的对象与源对象的类成员变量是同一个对象。
class Person implements Cloneable{
    public String name;
}

class Address{
    public String add;

    public Address(String add) {
        this.add = add;
    }
}
class Student extends Person{
    public Address address;

    public Student(String name, Address address) {
        this.name=name;
        this.address=address;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return name+":"+address.add;
    }
}

public class InstanceClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address add=new Address("handan");
        Student s1=new Student("du",add);
        Student s2=(Student)s1.clone();

        System.out.println(s1);
        System.out.println(s2);
        
        add.add="zhongguo";
        System.out.println(s1);
        System.out.println(s2);
    }
}

深度克隆一种方法是:

  1. 类中成员变量需要继承Cloneable接口,然后并重写clone()方法,将==方法修饰符修改为public==;
  2. 被克隆的类或者其父类实现Cloneable接口,然后重写clone()方法,将==方法修饰符修改为public==,并在方法中调用成员变量的clone方法;
  3. 基本思路同浅克隆。

另一种实现深度克隆的方式是序列化:==如果引用链过长,则我们可以通过序列化的方式进行克隆**,示例代码:
[注]:克隆不收transient限制:

try(FileOutputStream f=new FileOutputStream("E:\\object.dat");
    ObjectOutputStream o=new ObjectOutputStream(f)) {
        o.writeObject(s1);
} catch (IOException e) {
        e.printStackTrace();
}

try(FileInputStream f=new FileInputStream("E:\\object.dat");
    ObjectInputStream in=new ObjectInputStream(f)){
        Student s3=(Student)in.readObject();
        System.out.println(s3);
}catch (Exception e){
    e.printStackTrace();
}
  • 成员变量也需要实现Serializable接口;

克隆对象

标签:out   com   hand   修饰符   leo   继承   student   示例   ext   

原文地址:https://www.cnblogs.com/dugk/p/8900798.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!