博客
关于我
day19Java-其它IO-ObjectIn(Out)putStream-(反)序列化流
阅读量:268 次
发布时间:2019-03-01

本文共 4098 字,大约阅读时间需要 13 分钟。

ObjectInputStream与ObjectOutputStream - 序列化与反序列化流

在Java编程中,ObjectInputStream和ObjectOutputStream是处理对象序列化和反序列化的核心类。ObjectOutputStream用于将对象转化为流数据,以便在文本文件中存储或通过网络传输。而ObjectInputStream则用于将流数据还原为对象。这两者在数据传输和持久化存储中发挥着重要作用。

ObjectOutputStream - 序列化流

使用ObjectOutputStream进行对象序列化时,首先需要确保目标类实现了Serializable接口。该接口是一个标记接口,类通过实现它可以启用其序列化功能。如果未实现该接口的类将无法进行序列化或反序列化操作,会抛出NotSerializableException异常。

实现Serializable接口的重要性

以下是实现Serializable接口的示例代码:

public class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

如果类Person未实现Serializable接口,尝试将其序列化就会抛出以下错误信息:

Exception in thread "main" java.io.NotSerializableException: com.ginger.demo01.Person
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1185)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:349)
at com.ginger.demo01.ObjectInputStreamDemo.writer(ObjectInputStreamDemo.java:24)
at com.ginger.demo01.ObjectInputStreamDemo.main(ObjectInputStreamDemo.java:8)

ObjectInputStream - 反序列化流

在反序列化过程中,如果类没有指定序列化版本号(serialVersionUID),可能会出现InvalidClassException。以下是一个常见的解决方案:

  • 在类中手动指定序列化版本号:
  • public class Person implements Serializable {
    private static final long serialVersionUID = 6499259360078010285L;
    private String name;
    private int age;
    // 其他代码保持不变
    }
    1. 如果需要修改类结构后仍能读取已存在的序列化文件,可以通过在类中使用transient关键字来控制哪些字段参与序列化:
    2. public class Person implements Serializable {
      private static final long serialVersionUID = 6499259360078010285L;
      private String name;
      private transient String chinese; // 使用transient关键字使chinese字段不参与序列化
      // 其他代码保持不变
      }

      代码示例

      以下是一个完整的代码示例,展示了如何使用ObjectInputStream和ObjectOutputStream进行数据的读写操作:

      写入流数据

      public class ObjectInputStreamDemo {
      public static void main(String[] args) throws IOException, ClassNotFoundException {
      writer();
      }
      private static void writer() throws IOException {
      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
      Person p = new Person("格雷福斯", 40);
      oos.writeObject(p);
      oos.close();
      }
      }

      读取流数据

      public class ObjectInputStreamDemo {
      public static void main(String[] args) throws IOException, ClassNotFoundException {
      reader();
      }
      private static void reader() throws IOException, ClassNotFoundException {
      ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
      Object p = ois.readObject();
      System.out.println(p);
      ois.close();
      }
      }

      实体类定义

      以下是一个实现了Serializable接口的实体类:

      public class Person implements Serializable {
      private static final long serialVersionUID = 6499259360078010285L;
      private String name;
      private int age;
      private transient String chinese;
      public Person(String name, int age, String chinese) {
      this.name = name;
      this.age = age;
      this.chinese = chinese;
      }
      public String getName() {
      return name;
      }
      public void setName(String name) {
      this.name = name;
      }
      public int getAge() {
      return age;
      }
      public void setAge(int age) {
      this.age = age;
      }
      @Override
      public String toString() {
      return "Person{" +
      "name='" + name + '\'' +
      ", age=" + age +
      ", chinese='" + chinese + '\'' +
      '}';
      }
      }

      结果分析

      在实际应用中,如果没有指定serialVersionUID,可能会出现以下错误:

      InvalidClassException: com.ginger.demo01.Person; local class incompatible: 
      stream classdesc serialVersionUID = 311183030272692197,
      local class serialVersionUID = 6499259360078010285

      解决方法

    3. 确保所有修改后的类都包含相同的serialVersionUID值。
    4. 如果需要在修改类后仍能读取已存在的序列化文件,可以通过在类中使用transient关键字来控制哪些字段参与序列化。
    5. 结论

      通过以上方法,开发者可以实现对象的序列化和反序列化操作。在实际开发中,建议在类定义时手动指定serialVersionUID,并合理使用transient关键字,以确保序列化过程的稳定性和兼容性。

    转载地址:http://hlya.baihongyu.com/

    你可能感兴趣的文章
    NPOI将某个程序段耗时插入Excel
    查看>>
    NPOI格式设置
    查看>>
    NPOI设置单元格格式
    查看>>
    Npp删除选中行的Macro录制方式
    查看>>
    NR,NF,FNR
    查看>>
    nrf24l01+arduino
    查看>>
    nrf开发笔记一开发软件
    查看>>
    nrm —— 快速切换 NPM 源 (附带测速功能)
    查看>>
    nrm报错 [ERR_INVALID_ARG_TYPE]
    查看>>
    NS3 IP首部校验和
    查看>>
    NSDateFormatter的替代方法
    查看>>
    NSError 的使用方法
    查看>>
    NSGA-Ⅲ源代码
    查看>>
    nsis 安装脚本示例(转)
    查看>>
    NSJSON的用法(oc系统自带的解析方法)
    查看>>
    nslookup 的基本知识与命令详解
    查看>>
    NSNumber与NSInteger的区别 -bei
    查看>>
    NSOperation基本操作
    查看>>
    NSRange 范围
    查看>>
    NSSet集合 无序的 不能重复的
    查看>>