美文网首页
Head First Java 14 保存对象

Head First Java 14 保存对象

作者: 促集 | 来源:发表于2016-08-10 16:28 被阅读0次

    保存对象

    串流(Stream)

    • 串流分为连接用串流(connnection streams)和链接用串流(chain streams),连接用串流通常来连接来源或者目的地, typically a file, network socket connection, or the console. 链接用串流不能用来连接源或者目的地。Chain streams cannot connect to a source or destination and must be chained to a connection (or other) stream.

    File

    • File对象代表文件或者目录的路径,但不代表文件或者目录本身
    //创建代表已有文件的File对象
    File f = new File("Mycode.txt");
    //创建新的目录
    File dir = new File("MyDocuments");
    dir.mkdir();
    //列出目录下的内容
    if(dir.isDirectory()){
        String[] dirContents = dir.list();}
    //取得绝对路径
    System.out.println(dir.getAbsolutePath());
    //删除文件或目录
    boolean isDeleted = f.delete();
    

    序列化(Serialization)

    • 对象有状态行为两种属性,行为存储在类中,状态存储在每个个别的对象,需要存储对象状态的时候使用序列化(Serialization)
    //ObjectOutputStream与FileOutputStream都为OutputStream的子类,OutputStream为一个抽象类。
    //左边为对象字节流,右边为文件字节流,write向右,read向左
    //characterOne必须是一个可被序列化的对象,需要实现Serializable接口才可以
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("MyGame.ser"));
    oos.writeObject(characterOne);
    oos.close();
    
    • 当对象被序列化时,被该对象引用的实例化变量也被序列化,并且所有被引用的对象也都会被序列化

    • 序列化版图中如果有任何一个变量没有序列化成功,则整个序列化都失败。例如序列化Pond对象时,如果Duck类没有实现Serializable接口,则序列化失败

    • 如果某实例变量不能或不应该被序列化时,就把它标记为transient ,则序列化过程可以跳过这个实例变量。当序列化还原的时候,被transient的实例变量会以值为null的对象引用或0,false等默认primitive主数据类型返回

        public class Pond{
            public String name;
            public Duck duck = new Duck();
        }
    
        public class Pond{
            public String name;
            public transient Duck duck = new Duck();
        }
    
    • 如果一个对象序列化后被还原,且他的父类是不可序列化的,则父类的构造函数会跟着创建新的对象时一起执行

    • 如果两个对象都有引用实例变量指向相同的对象,那么他们在被序列化的时候只有一个引用对象会被存储,另一个会复原成指向该引用

    • 静态变量不会被序列化,因为static代表每个类一个而不是每个变量一个,所以对象被还原时,静态变量会维持类中原本的样子,而不是存储时的样子

    • 如果你的类可能在产生序列化对象之后继续演变,则会有与序列化时不同的serialVersionUID,那么在解序列化时则会失败。所以如果你的类可能在产生序列化对象之后继续演变,你可以手工获得版本ID,然后将其拷贝到类上,但你必须确定你的改变不会对解序列化造成伤害

    解序列化(Deserialization)

    //ObjectInputStream与FileInputStream都为InputStream的子类,InputStream为一个抽象类。
    //左边为对象字节流,右边为文件字节流,write向右,read向左
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("MyGame.ser"));
    Object one = ois.readObject();
    Object two = ois.readObject();
    GameCharacter elf = (GameCharacter) one;
    GameCharacter troll = (GameCharacter) two;
    ois.close();
    
    • 解序列化时Java虚拟机会尝试寻找和加载对象的类,如果找不到或无法加载该类,则会抛出异常。对于通过网络传送序列化对象来说,有一种机制可以让类使用URL来指定自己的位置,让你可以把序列化对象当作参数的一部分来传送,如果接受此调用的Java虚拟机没有此类,则它可以自动使用URL来取回并加载该类

    • 解序列化后新的对象会被配置在堆上,但构造函数不会执行,因为这样会把对象的状态抹去变成全新的状态。如果对象在继承树上有个不可序列化的祖先类,则该不可序列化类以及在它之上的类(就算可序列化也一样)构造函数都会执行,且一经启动,无法停止

    相关文章

      网友评论

          本文标题:Head First Java 14 保存对象

          本文链接:https://www.haomeiwen.com/subject/nsihsttx.html