Serializable接口序列化与反序列化

参考链接

我们在编写实现Serializable接口的类的时候,IDE会提示:需要增加一个Serial Version ID。

  • 为什么要增加?
  • 它是怎么计算出来的?
  • 有什么用?
  • 类实现Serializable接口的目的是为了可持久化,比如网络传输或本地存储。
    实现序列化很简单:

    1  public class Person implements Serializable {
    2    private String name;
    3    /*name属性的getter/setter方法省略*/
    4  }
  • 这里以Java消息服务方式传递该对象(即通过网络传递一个对象),定义在消息队列中数据类型为ObjectMessage,首先定义一个消息的生产者(Producer)。
    1 public class Producer{
    2   public static void main(String[] args){
    3     Person person = new Person();
    4     person.setName("Kong");
    5     //序列化,保存到磁盘上,
    6     SerializationUtils .writeObject(person);
    7   }
    8 }

    这里引入了一个工具类SerializableUtils,其作用是对一个类进行序列化和反序列化,并存储在硬盘上。

     1 public class SerializationUtils {
     2   private static String FILE_NAME = "D:/obj.bin";
     3   //序列化
     4   public static void writeObject(Serializable s){
     5     try{
     6             ObjectOutputStream oos = new ObjectOutputStream(new FlieOutputStream(FILE_NAME));
     7             oos.writeObject(s);
     8             oos.close();
     9         } catch (Exception e) {
    10             e.printStackTrace();
    11         }
    12   }
    13
    14 public static Object readObject(){
    15     Object obj  = null;
    16     //反序列化
    17     try{
    18           ObjectInputStream input = new ObjectInputStream(new FileInputStream(FILE_NAME));
    19           obj = input.readObject();
    20           input.close();
    21       } catch(Exception e) {
    22         e.printStackTrace();
    23       }
    24       return obj;
    25   }
    26 }

    通过对象序列化过程,把一个对象从内存块转化为可传输的数据流,然后通过网络发送消息到消费者那里,并进行反序列化,生成实例对象。

    public class Consumer{
      public static void main (String[] args) throws Exception{
        //反序列化
        Person p = (Person) SerializationUtils.readObject();
        System.out.println("name = "+ p.getName());
      }
    }

    这是序列化和反序列化得典型DEMO。
    有个问题:如果消息的生产者和消息的消费者 所参考的类(Person)有差异会出现什么情况?比如:消息生产者中的Person类增加一个age属性,而消费者没有增加该属性。在这种序列化和反序列化不一样的情况下,反序列化会报一个InvalidClassException异常,原因是序列化和反序列化所对应的类版本发生了变化,JVM不能把数据流转换为实例对象。
    那么JVM是通过什么来判断一个类的版本类型?
    通过SerialVersionUID,它可以隐式声明和显示声明,显示声明如下:

    private static final long serialVersionUID = xxxxL
    

    隐式声明即不声明,是编译器在 编译的时候通过包名,类名,继承关系、非私有的方法和属性,以及参数,返回值等各种计算出来,可以说是唯一的值。

    JVM在反序列化时会比较数据流的serialVersionUID与类中的serialVersionUID是否一样,如果相同,则认为类没有发什么改变呢,可以把数据流load为实例对象:如果不相同,则会报InvalidClassException异常。

    但是有时候类的改动很小,想把以前的对象反序列化过来,则需要显示的声明serialVersionUID,向JVM撒谎我的类没有改变。

原文地址:https://www.cnblogs.com/woyaodangxueba/p/10480465.html

时间: 2024-08-30 00:41:11

Serializable接口序列化与反序列化的相关文章

Serializable的序列化与反序列化

使用Serializable序列化,只要实现Serializable接口即可.一般情况下都会显示设置静态成员变量serialVersionUID为固定值.序列化时使用ObjectOutputStream写入,反序列化时使用ObjectInputStream读出. 如此简单,谁都会.但这是我碰到复杂点的情况,特作以下总结: 1.Serializable可继承:父类实现了序列化,子类也会自动实现序列化 PersonBean.java: public class PersonBean implemen

71 Serializable(序列化和反序列化)

对象的输出流:ObjectOutputStream  把对象输出到文件存储起来,我们称作为序列化对象的输入流:ObjectInputStream   把对象从文件中读取出来,我们称作为反序列化 ObjectOutputStream    构造方法:        ObjectOutputStream()            为完全重新实现 ObjectOutputStream 的子类提供一种方法,让它不必分配仅由 ObjectOutputStream 的实现使用的私有数据.        Ob

谈谈序列化—实体bean一定要实现Serializable接口?

导读:最近在做项目的过程中,发现一个问题,就是我们最开始的时候,传递参数包括返回类型,都有map类型.但是由于map每次都要匹配key值,很麻烦.所以在之后就将参数传递和返回类型全都改成了实体bean,并且让每个bean都实现了Serializable接口.然后,在这里的时候,就有点疑惑.首先:为什么要进行序列化:其次:每个实体bean都必须实现serializabel接口吗?最后:我做一些项目的时候,没有实现序列化,同样没什么影响,然后现在做项目需要序列化,到底什么时候应该进行序列化操作呢?

java 的序列化和反序列化的问题

引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口,使用 ObjectInputStream 和 ObjectOutputStream 进行对象的读写.然而在有些情况下,光知道这些还远远不够,文章列举了笔者遇到的一些真实情境,它们与 Java 序列化相关,通过分析情境出现的原因,使读者轻松牢记 Java 序列化中的一些高级认识. 回页首 文章结构 本

Java Serializable(序列化)的理解和总结、具体实现过程(转)

原文地址:http://www.apkbus.com/forum.php?mod=viewthread&tid=13576&fromuid=3402 Java Serializable(序列化)的理解和总结.具体实现过程 内存中的对象是怎么存在的?  内存中各种对象的状态是?  实例变量是什么(指的是实例化的对象吗)?    使用序列化的好处是什么? 1.序列化是干什么的?        简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出

对Java Serializable(序列化)的理解和总结(一)

导读:最近在做项目的过程中,发现一个问题,就是我们最开始的时候,传递参数包括返回类型,都有map类型.但是由于map每次都要匹配key值,很麻烦.所以在之后就将参数传递和返回类型全都改成了实体bean,并且让每个bean都实现了Serializable接口.然后,在这里的时候,就有点疑惑.首先:为什么要进行序列化:其次:每个实体bean都必须实现serializabel接口吗?最后:我做一些项目的时候,没有实现序列化,同样没什么影响,然后现在做项目需要序列化,到底什么时候应该进行序列化操作呢?

2.序列化与反序列化

Java 领域的对象如何传输 基于 socket 进行对象传输 先举个简单的例子,基于我们前面几次课程的只是,写一个 socket 通信的代码 User public class User { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } SocketServerProvider public static

夯实Java基础系列22:一文读懂Java序列化和反序列化

本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 文章首发于我的个人博客: www.how2playlife.com 本文参考 http://www.importnew.com/17964.html和 https://www.ibm.com/developerworks/cn/java/j-lo-serial/ 序列化与反序列化概念 序列化 (S

对象序列化和反序列化应该写为一个工具类

对象序列化和反序列化工具类 package com.umu.util; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.Object