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. fedora安装后,yum命令不能使用,Cannot retrieve metalink for repository: fedora. Please verify its path and try again 解决方法

    fedora安装后,yum命令不能使用,Cannot retrieve metalink for repository: fedora. Please verify its path and try ...

  2. 推荐一个 Java 实体映射工具 MapStruct

    声明: 1.DO(业务实体对象),DTO(数据传输对象). 2.我的代码中用到了 Lombok ,不了解的可以自行了解一下,了解的忽略这条就好. 在一个成熟的工程中,尤其是现在的分布式系统中,应用与应 ...

  3. js去除字符串两边的空格

    bless = bless.replace(/(^\s*)|(\s*$)/g, "") // 去掉两边的空格

  4. Python()- 面向对象三大特性----多态

    多态: python 生来支持多态白话:一种事物的多种形态 (动物可以继承给狗,也可以继承给猫) class Animal: pass class Dog(Animal): def attack(se ...

  5. hdu6212 祖玛(区间DP)

    题意 有一个长度为n的01串,我们可以在某个地方插入一个0或者1,那么如果有连续颜色相同的>=3个,那么这段就会消去,两边的合拢.问将所有01串消去,最少需要插入多少个.(n<=200) ...

  6. Windows平台kafka环境的搭建

    注意:Kafka的运行依赖于Zookeeper,所以在运行Kafka之前我们需要安装并运行Zookeeper 下载安装文件: http://kafka.apache.org/downloads.htm ...

  7. redis 实际应用中的缓存作用(转)

    有人说互联网用户是用脚投票的,这句话其实也从侧面说明了,用户体验是多么的重要:这就要求在软件架构设计时,不但要注重可靠性.安全性.可扩展性以及可维护性等等的一些指标,更要注重用户的体验,用户体验分很多 ...

  8. Jquery改动页面标题title其他JS失效

    Jquery代码   $("title").html("hello"); 后来仅仅好用以下这段js代码来实现 Js代码   document.title=&qu ...

  9. 深入浅出AOP(一)

    动态代理实现AOP: AOP事实上非常早之前依照做出来了一些东西,之所以不敢说做出来了.是由于它是什么?怎么实现?做出来的东西是不是?先前一直查资料.查到的资料跟着做.到后来发现,AOP越来越大,而非 ...

  10. Selenium系列之--01 简介【转】

    1.selenium 工具组件 1.1 selenium2,也称为selenium webdriver.webdriver原来是另一个自动化测试工具,后与selenium 合并了.webdriver直 ...