• 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 }

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

  • 相关阅读:
    Ubuntu中设置永久的DNS
    Ubuntu上OpenStack DashBoard主题修改的方案
    OpenStack 控制台不能不能访问的问题
    树莓派2试玩
    SharpMap V1.1 For Web教程系列之——地图展示
    剑指offer12 矩阵中的路径
    flex布局中关键词整理
    浏览器缓存 强缓存 协商缓存整理
    二叉搜索树中第K小的元素
    leetcode cs-notes-树(一)【js】
  • 原文地址:https://www.cnblogs.com/niujifei/p/11499141.html
Copyright © 2020-2023  润新知