0. 序列化的意义

从内存到本地即为本地化或者在网络中进行传输,或叫序列化,持久化。

某 Java 类实现 Serializable 接口的目的是为了可持久化(简单理解为本地化),比如网络传输或本地存储,为系统的分布式运行和异构部署提供先决支持条件。若没有序列化,我们熟悉的远程调用(RPC,无法读取远程主机内存中的任何目标,必须首选在远程将目标序列化),对象数据库都不可能存在。

1. 一个简单 demo

Serializable 为空接口,只是为了起到标识说明之义。

  • Person 类实现 Serializable 接口,这是一个简单的 JavaBean,实现了 Serializable 接口,可以在网络上传输,也可以本地存储然后读取。我们可以通过 Java 消息服务(Java Message Service)方式传递该对象(即通过网络传递一个对象),定义在消息队列中的数据类型为 ObjectMessage。

    public class Person implements Serializable {
    private String name; // 省略 getter、setter
    }
  • 序列化及反序列化客户端代码:

    public class Producer
    {
    final static String FILE_NAME = "C:/obj.bin";
    public static void main(String[] args)
    {
    Person person = new Person();
    person.setName("");
    SerializationUtils.writeObject(person, FILE_NAME);
    }
    }
    public class Conducer
    {
    final static String FILE_NAME = "C:/obj.bin";
    public static void main(String[] args)
    {
    Person p = (Person)SerializationUtils.readObject(FILE_NAME);
    p.getName();
    }
    }
  • 其中的 SerializationUtils 工具类如下:

    public class SerializationUtils
    {
    // 序列化
    public static void writeObject(Serializable s, String filename)
    {
    try
    {
    ObjectOutputStream oos = new ObjectOutputStream(
    new FileOutputStream(filename));
    oos.writeObject(s);
    oos.close();
    } catch (Exception e)
    {
    e.printStackTrace();
    }
    }
    // 反序列化
    public static Object readObject(String filename)
    {
    Object obj = null;
    try
    {
    ObjectInputStream ois = new ObjectInputStream(
    new FileInputStream(filename));
    ois.readObject();
    ois.close();
    } catch (Exception e)
    {
    e.printStackTrace();
    }
    return obj;
    }
    }

2. UID 的必要性

正因为分布和异构,无论是读取本地文件还是远程调用,本地是无法在编译期获取待获取的类的完整信息的(成员变量和函数)。也即有可能发生,消息的生产者和消息的消费者所参考的类(Person)有差异,比如消息生产者的 Person 类添加一个年龄字段,而相应的消费者没有增加该属性。

这种序列化和反序列化的类不一致的情形下,反序列时有可能会报一个 InvalidClassException 异常。原因就在于序列化和反序列化所对应的类版本发生了变化,JVM 不能把数据流转换为实例对象。那么,JVM 是根据什么来判断一个类版本的呢?

通过 SerialVersionUID,也叫流标志符(Stream Unique Identifier)

public class Person implements Serializable {
private static final long serialVersionUID = 55799L;
}

此时如果发生如下形式的不一致的情况,生产者增加年龄属性,消费端 Person 还保持以前的版本。此时,虽然物理上,生产者和消费者对应的类版本不同,但是显式声明的 serialVersionUID 相同,反序列化也可以运行,所带来的业务问题即是消费端无法读取新增的业务属性。

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

  1. Java 序列化和反序列化(三)Serializable 源码分析 - 2

    目录 Java 序列化和反序列化(三)Serializable 源码分析 - 2 1. ObjectStreamField 1.1 数据结构 1.2 构造函数 2. ObjectStreamClass ...

  2. Java 序列化和反序列化(二)Serializable 源码分析 - 1

    目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...

  3. Java 序列化和反序列化(一)Serializable 使用场景

    目录 Java 序列化和反序列化(一)Serializable 使用场景 1. 最简单的使用:Serializable 接口 2. 序列化 ID 的问题 3. 静态字段不会序列化 4. 屏蔽字段:tr ...

  4. Serializable详解(1):代码验证Java序列化与反序列化

    说明:本文为Serializable详解(1),最后两段内容在翻译上出现歧义(暂时未翻译),将在后续的Serializable(2)文中补充. 介绍:本文根据JDK英文文档翻译而成,本译文并非完全按照 ...

  5. Java序列化与反序列化(Serializable)

    Java序列化与反序列化(Serializable) 特别注意: 1.要序列化的类必须实现Serializable借口 2.在反序列化(读取对象)的时候必须额外捕获EOFException 3.序列化 ...

  6. Java序列化与反序列化

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列 ...

  7. [转] Java序列化与反序列化

    原文地址:http://blog.csdn.net/wangloveall/article/details/7992448 Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java ...

  8. java基础知识回顾之javaIO类--java序列化和反序列化

    /** *  * 一:理解序列化反序列化及其应用 * 序列化:把堆内存的对象转化成字节流的过程. * 反序列化:把字节流序列恢复重构成对象的过程. * 对象的序列化的用途:1.把对象的字节序列持久化, ...

  9. Java基础(五)-Java序列化与反序列化

    .output_wrapper pre code { font-family: Consolas, Inconsolata, Courier, monospace; display: block !i ...

随机推荐

  1. Android ShapeDrawable之OvalShape、RectShape、PaintDrawable、ArcShape

     Android ShapeDrawable之OvalShape.RectShape.PaintDrawable.ArcShape Android图形图像基础之OvalShape.RectShap ...

  2. CLR Via CSharp读书笔记(26) - 计算限制的异步操作

    执行上下文: 执行上下文包括安全设置(压缩栈.Thread的Principal属性和Windows身份),宿主设置(System.Threading.HostExecutionContextManag ...

  3. NYOJ301-递推求值

    递推求值 nyoj上矩阵专题里的10道题水了AC率最高的5道,惭愧,还不是完全自己写的,用了几乎两周的时间.模板题我是有自信写出来的,但对于高级一点的矩阵构造,我还是菜的抠脚. 这题感谢MQL大哥和她 ...

  4. 复(学)习化学时突然的一个 idea

    期中考试成功探底...但是某些化学问题还是很有信息学价值的... n 烷同分异构体计数. 这个题 fanhq666 出过,就是一个 dp. 设 f[i] 表示含有 i 个节点的无标号不同构的度数限制为 ...

  5. 【枚举】Southwestern Europe Regional Contest H - Sheldon Numbers

    https://vjudge.net/contest/174235#problem/H [题意] 求[x,y]之间有多少个Sheldon Number Sheldon Number是二进制满足以下条件 ...

  6. Java多线程干货系列—(四)volatile关键字

    原文地址:http://tengj.top/2016/05/06/threadvolatile4/ <h1 id="前言"><a href="#前言&q ...

  7. delphi操作xml学习笔记 之一 入门必读

    Delphi 对XML的支持---TXMLDocument类       Delphi7 支持对XML文档的操作,可以通过TXMLDocument类来实现对XML文档的读写.可以利用TXMLDocum ...

  8. npm Error: Cannot find module 'proto-list'

    Error: Cannot find module 'proto-list' at Function.Module._resolveFilename (module.js:338:15) at Fun ...

  9. NodeJS+MongoDB+AngularJS+Bootstrap书店示例

    目录 一.Bootstrap 1.1.添加引用 1.2.在页面中使用BootStrap 1.3.可视化布局 二.使用MongoDB创建数据库 2.1.启动MongoDB数据库 2.2.启动数据库GUI ...

  10. win8系统 如何不显示这台电脑的文件夹

    在win8系统中,默认有下面这种文件夹   只要打开注册表编辑器,找到下面所示的项目,删除所有子文件夹即可(最后剩下一个DelegateFolders不用管) [HKEY_LOCAL_MACHINE\ ...