Java IO---3---IO 序列化 ObjectOutputStream类 与 ObjectInputStream类

序列化

概述

         Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据对象的类型对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

         反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化对象的数据对象的类型对象中存储的数据信息,都可以用来在内存中创建对象。看图理解序列化:

Java IO---3---IO 序列化 ObjectOutputStream类 与 ObjectInputStream类

ObjectOutputStream类

java.io.ObjectOutputStream 类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。

构造方法

  • public ObjectOutputStream(OutputStream out): 创建一个指定OutputStream的ObjectOutputStream。

序列化操作

  1. 一个对象要想序列化,必须满足两个条件:
  • 该类必须实现java.io.Serializable 接口,Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException
  • 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。

2.写出对象方法

  • public final void writeObject (Object obj) : 将指定的对象写出。

ObjectInputStream类

ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

构造方法

  • public ObjectInputStream(InputStream in): 创建一个指定InputStream的ObjectInputStream。

反序列化操作1

         如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream读取对象的方法:

  • public final Object readObject () : 读取一个对象。

         对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个 ClassNotFoundException 异常。

反序列化操作2

         另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException异常。发生这个异常的原因如下:

  • 该类的序列版本号与从流中读取的类描述符的版本号不匹配
  • 该类包含未知数据类型
  • 该类没有可访问的无参数构造方法

序列化实现

被序列化类: 想要被 序列化,需要实现 Serializable 接口。假如,有属性不需要被序列化,需要加上 瞬态关键字transient 关键字

public class 被序列化类  implements Serializable {
    public String love;
    public transient String name;
    public int age;

    public void show(){
        System.out.println("mylove="+love+"---myname="+name+"---myage="+age);
    }
}

使序列化:

public class 使序列化 {
    public static void main(String[] args) {

        被序列化类 u=new 被序列化类();
        u.name="张三";
        u.love="钓鱼";
        u.age=89;

        try {
            ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("D:\\夏季的笔记的消息\\图片\\寒假图片\\实验性的文件夹\\IO\\序列文件.txt"));
            out.writeObject(u);
            out.close();

            System.out.println("对象中除了name,其它都被序列化了");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

反序列化:

 public class 反序列化 {
    public static void main(String[] args) {
        try {
            ObjectInputStream in=new ObjectInputStream(new FileInputStream("D:\\夏季的笔记的消息\\图片\\寒假图片\\实验性的文件夹\\IO\\序列文件.txt"));
            被序列化类 u=(被序列化类) in.readObject();

            u.show();

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

}
上一篇:transient关键字的作用以及几个疑问的解决


下一篇:序列化与反序列化