序列化 — Java序列化

一.序列化定义

Wike中对序列化的定义如下:

In computing, serialization (or serialisation) is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer) or transmitted (for example, across a network connection link) and reconstructed later (possibly in a different computer environment).

序列化是将数据结构或者对象状态转化为另一种可以存储或者传输的格式。

二.Java序列化

在Java世界中一切皆对象Object,然而Object是Java中定义的数据格式,是语言层面表现出来的编程格式。然而Object对象无法直接存储在存储器中,也无法直接通过网络进行传递。能经过存储和传递的必然是以字节或者字符的形式表现出来。

为此Java从jdk 1.1便开始提供了序列化机制。对于Java程序员而言,Serializable一定是不陌生的,它是Java序列化的起点。本文将从以下几点说明Java序列化:

1. Serializable接口

在Java中,需要序列化的对象都需要实现Serializable接口。该接口只是一个纯粹的标记接口,其中未定义任何需要实现的接口方法。Java在序列化时检查,是否实现Serializable接口,如果未实现,在序列化时,将会抛出NotSerializableException异常。

在序列化的对象中一般需要有不重复的serialVersionUID,它用来标识序列化类的版本号。在反序列化时,需要验证反序列化对象的serialVersionUID与其是否一致。如果不一致则将会抛出InvalidClassException。

一个需要序列化的类,可以明确指定serialVersionUID。该字段是long型字段,需要是static和final。如果serialVersionUID没有明确指出,在序列化运行时,将会根据这个类的各个方面信息计算出一个默认的serialVersionUID值。

如下Person类可以被序列化:

public class Person implements Serializable {

    private static final long serialVersionUID = 914170721026336909L;

    private String name;
    private int 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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
2.序列化对象的方式

Java序列化对象提供了ObjectOutputStream用于序列化对象,将对象序列化的字节。提供了ObjectInputStream从二进制字节中反序列化生成对象。

具体使用方式也非常简单:

static void simpleSerialization() throws IOException, ClassNotFoundException {
    Person person = new Person();
    person.setName("huaijin");
    person.setAge(30);
    System.out.println("Serialization, " + person);

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("person.bin"));
    out.writeObject(person);

    ObjectInputStream in = new ObjectInputStream(new FileInputStream("person.bin"));
    Person desPerson = (Person) in.readObject();
    System.out.println("Deserialization, " + desPerson);
}

为了能够在序列化时,能够做一些特定处理,制定针对性的序列化,Java提供了

 private void writeObject(java.ioObjectOutputStream out) throws IOException;

 private void readObject(java.io.ObjectInputStream in) throws IOException,
    ClassNotFoundException;

writeObject和readObject方法可供序列化类实现,定制在序列化过程中自身特殊的方式。如下:

 private void writeObject(ObjectOutputStream out) throws IOException {
     out.writeUTF(this.name);
     out.writeInt(this.age);
 }

private void readObject(ObjectInputStream in) throws IOException,
        ClassNotFoundException {
    this.name = in.readUTF();
    this.age = in.readInt();
}

可以根据需求,为特殊的场景定制对象相应的序列化方式。比如,可以可以对对象的某个字段进行特殊处理后再进行序列化,也可以忽略某个字段不进行序列化,对安全字段进行加密处理等等。

在整个序列化过程中,会写入对象的类信息、类签名、所有的非transient和非static域。对于多次引用同一个对象,采用共享的序列化机制。

3. Java序列化弊端

虽然Java序列化是JDK提供的基础能力,但是它并不是很优秀:

  1. Java的序列化性能不足
  2. 序列化后的字节体积较大

这两点对于网络应用而言,非常致命。序列化带来的应用延迟和序列化的数据体积较大造成网络传输延迟,内存消耗较高等等,与互联网应用要求的低延迟,高响应相悖。

参考

Java 序列化的高级认识
Java Object Serialization Specification

原文地址:https://www.cnblogs.com/lxyit/p/12511591.html

时间: 2024-08-02 19:11:22

序列化 — Java序列化的相关文章

Java序列化Serializable和Externalizable

纸上得来终觉浅,绝知此事要躬行  --陆游       问渠那得清如许,为有源头活水来  --朱熹 什么是Java序列化?为什么出现Java序列化?如何实现Java序列化? 一.什么是Java序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 二.为什么出现Java序列化 两个进程之间进行通信时,须要传输各种信息.比方文本,图像,声音等等,这些信息是通过二进制流的形式进行传输的. 那么进程之间是不是也能够传递对象数据呢?答案是

Java序列化的作用

很多人都认为Java序列化的作用有以下两方面: 1) 把对象的字节序列永久地保存到硬盘上(通常存放在一个文件中): 2) 在网络上传送对象的字节序列. 可是我有一个疑问:第一个作用在什么情况会用到呢?第二个作用在什么情况会用到呢? 答: 归纳起来,就是把你的数据换个时间和/或换个地方,继续使用 换个时间,比如存盘 换个地方,比如网络传输 当然,实现"换个时间/地方用"的方式很多很多 正解...真正自己去序列化的还是比较少的,很多框架里面都做好了的..类似序列化功能的实现方式很多,不一定

Java 序列化深入分析

序列化机制介绍 ??序列化是指把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中.序列化后的字节流保存了Java对 象的状态以及相关的描述信息.客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象.本质上讲,序列化就是把实体对象状态按照一定的格式写入到有序字节流,反序列化就是从有序字节流重建对象,恢复对象状态.序列化机制的核心作用就是对象状态的 保存与重建. Java序列化机制解析 ??Java API提供了对序列化的支持,要实

Java 序列化与反序列化

1.什么是序列化?为什么要序列化? Java 序列化就是指将对象转换为字节序列的过程,而反序列化则是只将字节序列转换成目标对象的过程. 我们都知道,在进行浏览器访问的时候,我们看到的文本.图片.音频.视频等都是通过二进制序列进行传输的,那么如果我们需要将Java对象进行传输的时候,是不是也应该先将对象进行序列化?答案是肯定的,我们需要先将Java对象进行序列化,然后通过网络,IO进行传输,当到达目的地之后,再进行反序列化获取到我们想要的对象,最后完成通信. 2.如何实现序列化 2.1.使用到JD

Java序列化(Serialization)

关于Java的序列化的文章在网上已经够多了,在这里写关于Java序列化的文章是对自己关于这方面的的一种总结,结合以前的开发经验与网上的资料,写了这篇文章,对自己是有着巩固记忆的作用,也希望能够对大家有一定帮助. 一.什么是序列化(Serialization)? 序列化是Java提供的一种机制,将对象转化成字节序列,在字节序列中保存了对象的数据.对象的类型的信息与存储在对象中的数据的类型.序列化实际上就是将保存对象的"状态",可以方便以后的程序使用或者通过网络传输到另一台主机使用.一般来

Java 序列化Serializable

1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.   2.什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候: 3.如何实现序列化 将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个

【总结】你所不知道的Java序列化

我们都知道,Java序列化可以让我们记录下运行时的对象状态(对象实例域的值),也就是我们经常说的对象持久化 .这个过程其实是非常复杂的,这里我们就好好理解一下Java的对象序列化. 1. 首先我们要搞清楚,Java对象序列化是将 对象的实例域数据( 包括private私有域) 进行持久化存储.而并非是将整个对象所属的类信息进行存储. 其实了解JVM的话,我们就能明白这一点了.实际上堆中所存储的对象包含了实例域数据值以及指向类信息的地址,而对象所属的类信息却存放在方法区中.当我们要对持久层数据反序

Hadoop序列化与Java序列化

序列化就是把内存中的对象的状态信息转换成字节序列,以便于存储(持久化)和网络传输 反序列化就是就将收到的字节序列或者是硬盘的持久化数据,转换成内存中的对象. 1.JDK的序列化 只要实现了serializable接口就能实现序列化与反序列化,一定要加上序列化版本ID serialVersionUID,这个是用来识别序列化的之前的类到底是哪一个.比如希望类的不同版本对序列化兼容,需要确保类的不同版本具有相同的serialVersionUID: Java序列化算法需要考虑: 将对象实例相关的类元数据

深入分析java序列化

概念 先来点简单的概念: what?why? 什么是序列化?为什么要序列化? 答曰:将java对象转成字节序列,用以传输和保存 where? 使用场景是什么? 答曰:对象的传输:状态的备份,例如jvm的dump文件: 好了,不装*了,下面说的详细点.其实对象的序列化主要有两种用途: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中 在网络上传送对象的字节序列 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Sessio