import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args){
//        MyWorld.test();
        ATest.test();
    }
}

/*
    只要把任何对象序列化到单一的流中,就可以恢复出与我们写时一样的对象网,并且没有任何
    意外重复复制的对象。
 */

class House implements Serializable {
    //
}

class Animal implements Serializable {
    private String name;
    private House house;

    public Animal(String name, House house) {
        this.name=name;
        this.house=house;
    }

    public String toString() {
        return name+" ["+house+"] ";
    }
}

class MyWorld {
    public static void test() {
        try {
            /*
                问题:
                    1.animals中每个animal都使用同一个house,序列化时,house会不会被序列多个
             */
            House house = new House();
            List<Animal> animals = new ArrayList<>();
            animals.add(new Animal("A", house));
            animals.add(new Animal("B", house));
            animals.add(new Animal("C", house));

            System.out.println("animals:" + animals);

            //创建输出流
            ByteArrayOutputStream bstream = new ByteArrayOutputStream();
            ObjectOutputStream out1 = new ObjectOutputStream(bstream);
            out1.writeObject(animals);
            out1.writeObject(animals);
            out1.flush();

            ByteArrayOutputStream bstream2 = new ByteArrayOutputStream();
            ObjectOutputStream out2 = new ObjectOutputStream(bstream2);
            out2.writeObject(animals);
            out2.flush();

            //创建输入流
            ObjectInputStream in1 = new ObjectInputStream(
                    new ByteArrayInputStream(bstream.toByteArray()));
            ObjectInputStream in2 = new ObjectInputStream(
                    new ByteArrayInputStream(bstream2.toByteArray()));

            List
                    animals1 = (List)in1.readObject(),
                    animals2 = (List)in1.readObject(),
                    animals3 = (List)in2.readObject();

            System.out.println("animals1:" + animals1);
            System.out.println("animals2:" + animals2);
            System.out.println("animals3:" + animals3);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

/*
    问题:
        书中说,我们写出第一个对象和写出最后一个对象期间改变了这些对象的状态,但是又说
        只要我们序列化到同一个流中,就能恢复和写时一样的对象网。问题是,如果一个对象我
        第一写入时是x值,我改变了这个值为y,又写一次,那我恢复时,得到的对象的值是多少
        呢?

    输出结果:
        a1.a: 10
        a2.a: 10
        a1:A@568db2f2
        a2:A@568db2f2

    分析:
        我不知道这是为什么哦,感觉很奇怪,第二次的操作跟没操作一样的
 */
class A implements Serializable{
    private int a;

    public A(int a) {
        this.a = a;
    }

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }
}

class ATest{
    public static void test() {
        A a = new A(10);

        try{

            //创建输出流
            ByteArrayOutputStream bstream = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(bstream);
            out.writeObject(a);

            //改变a的值
            a.setA(100);
            //再次写入
            out.writeObject(a);

            out.flush();

            //创建输入流
            ObjectInputStream in = new ObjectInputStream(
                    new ByteArrayInputStream(bstream.toByteArray()));

            A a1 = (A)in.readObject();
            A a2 = (A)in.readObject();

            System.out.println("a1.a: "+a1.getA());
            System.out.println("a2.a: "+a2.getA());
            System.out.println("a1:"+a1);
            System.out.println("a2:"+a2);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

/*
    如果我们想保存状态,最安全的做法是将其作为“原子”操作进行序列化。如果我们
    序列化了某些东西,再去做其他的一些工作,再来序列化更多的东西,如此等等,
    那么将无法安全的保存系统状态。取而代之的是,将构成系统状态的所有对象都置
    入单一容器内,并在一个操作中将该容器直接写出。然后同样只需要一次方法调用
    ,即可以恢复状态
 */

Java编程思想:序列化深层部分的更多相关文章

  1. 《Java编程思想》读书笔记(二)

    三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...

  2. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

  3. java编程思想

    Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理 ...

  4. 《Java编程思想》读书笔记

    前言 这个月一直没更新,就是一直在读这本<Java编程思想>,这本书可以在Java业界被传神的一本书,无论谁谈起这本书都说好,不管这个人是否真的读过这本书,都说啊,这本书很好.然后再看这边 ...

  5. JAVA编程思想读书笔记(四)--对象的克隆

    接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...

  6. JAVA编程思想——分析阅读

    需要源码.JDK1.6 .编码风格参考阿里java规约 7/12开始 有点意识到自己喜欢理论大而泛的模糊知识的学习,而不喜欢实践和细节的打磨,是因为粗心浮躁导致的么? cron表达式使用 设计能力.领 ...

  7. Java编程思想 笔记

    date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...

  8. 《Java编程思想》读书笔记(三)

    前言:三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十一章到第十六章的内容,这一次 ...

  9. 《Java编程思想》读书笔记(五)

    前言:本文是<Java编程思想>读书笔记系列的最后一章,本章的内容很多,需要细读慢慢去理解,文中的示例最好在自己电脑上多运行几次,相关示例完整代码放在码云上了,码云地址:https://g ...

  10. JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)

    switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...

随机推荐

  1. 第一个kotlin程序

    class ccc { companion object { @JvmStatic fun main(args: Array<String>) { println("hello! ...

  2. GIS基础软件及操作(四)

    原文 GIS基础软件及操作(四) 练习四.空间数据处理 1.空间数据处理(融合.合并.剪切.交叉.合并)2.设置地图投影及投影变换 空间数据处理 数据:云南县界.shp; Clip.shp西双版纳森林 ...

  3. 微信小程序把玩(五)页面生命周期

    原文:微信小程序把玩(五)页面生命周期 这里只要熟悉页面的基本生命周期即可,业务在指定生命周期函数内书写. 以下是官网给出的生命周期函数方法和状态图 上面的生周期函数图对于做Android 或者IOS ...

  4. 如何在 Linux 中添加一块大于 2TB 的新磁盘?

    你有没有试过使用 fdisk 对大于 2TB 的硬盘进行分区,并且纳闷为什么会得到需要使用 GPT 的警告? 是的,你看到的没错.我们无法使用 fdisk 对大于 2TB 的硬盘进行分区. 在这种情况 ...

  5. Tobject 类解析

    TObject = class    //创建    constructor Create;    //释放    procedure Free;    //初始化实列    class functi ...

  6. Office Add-in Model 为 Outlook Mail Add-in 提供的 JavaScript API 介绍

    本文所讨论的 Mailbox API是指在 Mail Add-in 中可调用的 JavaScript API.开发者可以利用这些API 实现 Add-in 和 Outlook 的交互(数据读取与写入) ...

  7. 更换Qt QtEmbedded库的版本出现问题及解决(交叉编译OpenSSL)

    近日将QtEmbedded库的版本由4.7.0更新到4.7.4.工具链并未改变,仍为 Target: arm-none-linux-gnueabiConfigured with: ......Thre ...

  8. C#实现任意源组播与特定源组播

    IP组播通信需要一个特殊的组播地址,IP组播地址是一组D类IP地址,范围从224.0.0.0 到 239.255.255.255.其中还有很多地址是为特殊的目的保留的.224.0.0.0到224.0. ...

  9. SQL 游标知识整理

    游标声明格: declare 游标名称 cursor (游标关键字) for 游标操作对象(select * from 表名称)游标使用: open 游标名称; fetch first from 游标 ...

  10. python中的基本数据类型之列表,元组

    一.列表 1.什么是列表. 列表是python的基本数据类型之一,用[]来表示,可以存放各种数据类型(什么都能装,能装对象的对象) 列表相比于字符串,不仅可以存放不同类型的数据,而且可以存放大量的数据 ...