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. zoj 2201 No Brainer

    No Brainer Time Limit: 2 Seconds      Memory Limit: 65536 KB Zombies love to eat brains. Yum. Input ...

  2. ACboy needs your help(分组背包)

    ACboy has N courses this term, and he plans to spend at most M days on study.Of course,the profit he ...

  3. POJ 2352 star level

    题目链接: http://poj.org/problem?id=2352 题目大意:对于每一颗星星来说,都有一个属于自己的level,这个值为其他星星x,y坐标均不大于本星星的个数.输入时按先y由小到 ...

  4. SDWebImage实现分析

    该博文来自南峰子的技术博客,文章从下载和缓存俩个大的组件分析到里面一些核心方法的实现,条理清晰,相对于一些一上来就通篇分析实现思路的技术文章, 这篇的讲解思路明确,框架架构也讲的比较清楚.看完这篇再去 ...

  5. poj3694+hdu2460 求桥+缩点+LCA/tarjan

    这个题使我更深理解了TARJAN算法,题意:无向图,每添加一条边后文桥的数量,三种解法:(按时间顺序),1,暴力,每每求桥,听说这样能过,我没过,用的hash判重,这次有俩个参数(n->10w, ...

  6. HDU 5514 容斥原理

    Frogs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  7. 一个开发的Linux使用心得总结

    Liunx介绍 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和网络协 ...

  8. Excel小tips - 如何实现多列成绩统一排名

    本文参考:http://mp.weixin.qq.com/s/XR49hyG9Cods7rOcsM-tRg 如果有以下数据文件,需要进行成绩排名. 第一步:先在成绩列后边添加一列,用来显示名次.如下: ...

  9. ECC数据结构

    在SM2 ECC算法中,有针对签名加密的数据结构,下面对这些结构进行分析 #define ECCref_MAX_BITS 512 #define ECCref_MAX_LEN ((ECCref_MAX ...

  10. Java多线程导致的的一个事物性问题

    业务场景 我们如今有一个类似于文件上传的功能.各个子网站接受业务,业务上传文件,各个子网站的文件须要提交到总网站保存.文件是按批次提交到总网站的,也就是说,一个批次以下约有几百个文件. 考虑到白天提交 ...