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

本文共 4018 字,大约阅读时间需要 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/

    你可能感兴趣的文章
    python各种库安装
    查看>>
    python可视化matplotlib_如何使用Python中最强大的可视化工具Matplotlib?
    查看>>
    python可维护性_使用这7大神器,让你的Python 代码更容易于维护
    查看>>
    Python只运行一次while循环
    查看>>
    python变量的详细教程_Python零基础入门教程之语法入门[变量](第二期)
    查看>>
    Python变量命名方法-ChatGPT4o作答
    查看>>
    Python变量与运算符
    查看>>
    Python变量/运算符/函数/模块/string
    查看>>
    python发送邮件的时候出现 error (535, b‘5.7.3 Authentication unsuccessful‘) 解决方法
    查看>>
    python系列【仅供参考】:python flask框架 debug功能
    查看>>
    python发送notes邮件_使用python在Lotus Notes中发送邮件
    查看>>
    Python双版本下创建一个Scrapy(西瓜皮)项目
    查看>>
    Python双版本下No module named 'requests'
    查看>>
    python及pycharm2018软件安装教程
    查看>>
    python去重txt文本_Python实现的txt文件去重功能示例
    查看>>
    python去掉列表的逗号,从Python列表项中删除标点符号
    查看>>
    Python卸载所有包
    查看>>
    python单线程下实现多个socket并发
    查看>>
    Python单元测试框架介绍(超详细~)
    查看>>
    Python单元测试框架
    查看>>