Java 之 ObjectInputStream 类


ObjectInputStream 类

  1、概述

      java.io.ObjectInputStream extends InputStream

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

  2、构造方法

ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。

    参数:InputStream in:字节输入流

  3、特有的成员方法

Object readObject() 从 ObjectInputStream 读取对象。

  

  4、使用步骤

    ① 创建ObjectInputStream对象,构造方法中传递字节输入流

    ② 使用ObjectInputStream对象中的方法readObject读取保存对象的文件

    ③ 释放资源

    ④ 使用读取出来的对象(打印)

  5、注意

     readObject方法声明抛出了ClassNotFoundException(class文件找不到异常)

    当不存在对象的 class 文件时抛出此异常:

    反序列化的前提:

      ① 类必须实现 Seriaizable 

      ② 必须存在类对应的 class 文件

  6、反序列化操作1

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

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

      Demo:

 1 public static void main(String [] args) {  2     Employee e = null;  3     try {  4         // 创建反序列化流
 5         FileInputStream fileIn = new FileInputStream("employee.txt");  6         ObjectInputStream in = new ObjectInputStream(fileIn);  7         // 读取一个对象
 8         e = (Employee) in.readObject();  9         // 释放资源
10  in.close(); 11  fileIn.close(); 12     }catch(IOException i) { 13         // 捕获其他异常
14  i.printStackTrace(); 15        return; 16     }catch(ClassNotFoundException c) { 17         // 捕获类找不到异常
18         System.out.println("Employee class not found"); 19  c.printStackTrace(); 20         return; 21  } 22         // 无异常,直接打印输出
23  System.out.println(e); 24 
25  } 26 }

 

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

  7、反序列化操作2

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

    原因如下

      ① 该类的序列版本号与从流中读取的类描述符的版本号不匹配

      ② 该类包含未知数据类型

      ③ 该类没有可访问的无参数构造方法

      Serializable 接口给需要序列化的类,提供了一个序列版本号serialVersionUID 该版本号的目的在于验证序列化的对象和对应类是否版本匹配。

    解决方法:

      ① 修改本地的serialVersionUID为流中的serialVersionUID

      ② 在当初实现Serializable接口时,就固定一个serialVersionUID,这样每次编译就不会自动生成一个新的serialVersionUID

    Demo:

 1 public class Employee implements java.io.Serializable {  2     // 加入序列版本号
 3     private static final long serialVersionUID = 1L;  4     public String name;  5     public String address;  6     // 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.
 7     public int eid;  8     public void addressCheck() {  9         System.out.println("Address check : " + name + " ‐‐ " + address); 10  } 11 }

   序列号冲突异常的原理和解决方案:

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM