zoukankan      html  css  js  c++  java
  • Java基础回顾 —RandomAccessFile/ 序列化

    1. RandomAccessFile 实现了DataOutput, DataInput接口。
      所以它可以writeByte(), writeInt()…. 同时也可以readByte(), readInt()。
      有seek( )方法来访问文件,可以从文件的任意位置读写文件,这个seek可以看做文件指针吧,而这个类,我们用的最多的无疑是:Java多线程文件下载.

    2. 序列化:
      对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫对象序列化。

    3. 持久化:
      将一个对象保存到永久存储设备上称为持久化。

    4. 一个对象要能够实现序列化,必须实现Serializable接口,或者Externalizable( 可以根据自己的需要选择序列化的属性)接口。如果一个类可以序列化,那么它的子类也可以序列化。

    5. Serializable接口没有定义任何方法,是一个标识性的接口(Mark Interface)。

    6. 序列化注意:

      • 当一个对象被序列化时,只有属性会被保存,方法不会保存的,并且只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
      • 如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
      • 如果一个可序列化类有多个父类(直接父类和间接父类),那么这些父类要么有无参构造函数,要么也是可以序列化的,否则会抛出InvalidClassException。如果父类不可序列化,只是带有无参构造函数,则该父类中定义的成员变量值不会序列化到二进制流中。
      • 多次序列化同一个对象问题:
        因为可能一个类的两个实例共同持有另一个类的一个实例,比如两个老师t1、t2有同一个学生s1,这样序列化t1和t2的时候分别会序列化s1对象,再反序列化的时候,会产生两个s1对象,且这两个对象不是同一个对象,所以Java序列化机制才采用一种特殊的序列化算法,使得所有保存到磁盘的对象都有一个序列化编号。当程序试图序列化一个对象时,先判断该对象是否已经被序列化过,只有在本次虚拟机中从未被序列化的对象,才会被转换成字节并输出。如果对象已经序列化过,则只是直接输出一个序列化编号,而不是再次重新序列化该对象。(所以同一个对象只有第一次序列化时才会被转化字节写入磁盘,要注意的是在序列化之后如果修改对象的实例变量,再进行实例化,也不会被输出,反序列化之后得到的依然是第一次序列化的对象)。
      • 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出NotSerializableException.我们可以将这个引用标记为transient,那个对象仍可序列化。
    7. ObjectOutput接口:(对DataInput和DataOutput接口进行了扩展,提供了对对象、数组、String的读写操作)
      继承DataOutput接口,并且支持对象的序列化,特别是writeObject()方法,被称为序列化一个对象,所有这些方法在出错的情况下引发IOException异常。

    8. ObjectOutputStream:
      将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。(所有对象(包括 String 和数组)都可以通过 writeObject 写入,可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象)

    9. ObjectInput接口:
      继承DataInput接口,支持对象序列化,readObject()方法,叫反序列化对象。

    10. ObjecInputStream:
      对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。

      tips1: serialVersionUID的作用是为了避免序列化和反序列化过程中类被修改或者JDK版本兼容性的问题
      - 如果类只是修改了方法,则序列化与反序列化不受影响。
      - 如果修改了static变量或者transient实例变量,同样也不受影响。
      - 如果修改了非transient实例变量,且对象流中对象与新类实例变量定义不相同,则反序列化失败。

      tips2: 最好只在需要被序列化对象的类实现Serializable接口,避免以后版本升级中,接口中添加新的方法
      tips3: 对于使用Externalizable实现序列化的对象的类必须提供一个无参构造方法,因为反序列化时默认调用无参构造实例化对象。这个与Serializable接口不同。
      tips4: 使用Externalizable进行部分属性序列化会比较麻烦;Serializable要想实现部分属性序列化,则可以使用transient关键字进行声明。

    Git Serizlizable code

  • 相关阅读:
    BZOJ.3884.上帝与集合的正确用法(扩展欧拉定理)
    HDU.5608.function(杜教筛)
    HDU.5628.Clarke and math(狄利克雷卷积 快速幂)
    51Nod.1244.莫比乌斯函数之和(杜教筛)
    SPOJ.Visible Lattice Points(莫比乌斯反演)
    BZOJ.2301.[HAOI2011]Problem B(莫比乌斯反演 容斥)
    BZOJ.2242.[SDOI2011]计算器(扩展欧几里得 BSGS)
    Codeforces757E.Bash Plays With Functions(积性函数 DP)
    插值法
    2、Windows下安装配置Redis
  • 原文地址:https://www.cnblogs.com/nextStep/p/6691240.html
Copyright © 2011-2022 走看看