其他分享
首页 > 其他分享> > 【当年笔记】克隆和序列化

【当年笔记】克隆和序列化

作者:互联网

1.浅克隆

需要克隆的对象必须实现 Cloneable 接口,并重写 clone() 方法,即可实现对此对象的克隆。 只会复制对象的值类型,而不会复制对象的引用类型。

2.深克隆

深克隆就是复制整个对象信息,包含值类型和引用类型。

2.1深克隆实现方式

class CloneTest {
        public static void main(String[] args) throws CloneNotSupportedException {
            BirdChild birdChild = new BirdChild();
            birdChild.name = "小小鸟";
            Bird bird = new Bird();
            bird.name = "小鸟";
            bird.birdChild = birdChild;
            // 使用序列化克隆对象
            Bird bird2 = CloneUtils.clone(bird);
            bird2.name = "黄雀";
            bird2.birdChild.name = "小黄雀";
            System.out.println("bird name:" + bird.name);
            System.out.println("bird child name:" + bird.birdChild.name);
            System.out.println("bird name 2:" + bird2.name);
            System.out.println("bird child name 2:" + bird2.birdChild.name);
        }
    }
    class CloneUtils {
        public static <T extends Serializable> T clone(T obj) {
            T cloneObj = null;
            try {
                //写入字节流
                ByteArrayOutputStream bo = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bo);
                oos.writeObject(obj);
                oos.close();
                //分配内存,写入原始对象,生成新对象
                ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());//获取上面的输出字节流
                ObjectInputStream oi = new ObjectInputStream(bi);
                //返回生成的新对象
                cloneObj = (T) oi.readObject();
                oi.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return cloneObj;
        }
    }

深克隆实现方式二:所有引用类型都实现克隆

    class CloneableTest {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
        ParrotChild parrotChild = new ParrotChild();
            parrotChild.name = "小鹦鹉";
            Parrot parrot = new Parrot();
            parrot.name = "大鹦鹉";
            parrot.parrotChild = parrotChild;
            // 克隆
            Parrot parrot2 = (Parrot) parrot.clone();
            parrot2.name = "老鹦鹉";
            parrot2.parrotChild.name = "少鹦鹉";
            System.out.println("parrot name:" + parrot.name);
            System.out.println("parrot child name:" + parrot.parrotChild.name);
            System.out.println("parrot name 2:" + parrot2.name);
            System.out.println("parrot child name 2:" + parrot2.parrotChild.name);
        }
     }
    class Parrot implements Cloneable {
        public String name;
        public ParrotChild parrotChild;
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Parrot bird = (Parrot) super.clone();
            bird.parrotChild = (ParrotChild) parrotChild.clone();
            return bird;
        }
    }
    class ParrotChild implements Cloneable {
        public String name;
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }

3.序列化和反序列化

将对象转换成二进制流的过程叫做序列化,把二进制流恢复为数据对象的过程就称之为反序列化

3.1序列化和反序列参考代码

先把对象序列化到磁盘,再从磁盘中反序列化出对象:


    class SerializableTest {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            // 对象赋值
            User user = new User();
            user.setName("老王");
            user.setAge(30);
            System.out.println(user);
            // 创建输出流(序列化内容到磁盘)
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.out"));
            // 序列化对象
            oos.writeObject(user);
            oos.flush();
            oos.close();
            // 创建输入流(从磁盘反序列化)
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.out"));
            // 反序列化
            User user2 = (User) ois.readObject();
            ois.close();
            System.out.println(user2);
        }
    }
    class User implements Serializable {
        private static final long serialVersionUID = 3831264392873197003L;
        private String name;
        private int age;
        @Override
        public String toString() {
            return "{name:" + name + ",age:" + age + "}";
        }
        // setter/getter...
        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;
        }
    }

标签:克隆,对象,笔记,new,序列化,bird,name
来源: https://www.cnblogs.com/Fanxc/p/16356471.html