Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。

将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。

整个过程都是Java虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。

类ObjectInputStream 和ObjectOutputStream是高层次的数据流,它们包含序列化和反序列化对象的方法。

ObjectOutputStream 类包含很多写方法来写各种数据类型,但是一个特别的方法例外:

public final void writeObject(Object x) throws IOException

上面的方法序列化一个对象,并将它发送到输出流。相似的ObjectInputStream 类包含如下反序列化一个对象的方法:

public final Object readObject() throws IOException,
ClassNotFoundException

该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。

为了演示序列化在Java中是怎样工作的,我将使用之前教程中提到的Employee类,假设我们定义了如下的Employee类,该类实现了Serializable 接口。

public class Employee implements java.io.Serializable
{
public String name;
public String address;
public transient int SSN;
public int number;
public void mailCheck()
{
System.out.println("Mailing a check to " + name
+ " " + address);
}
}

请注意,一个类的对象要想序列化成功,必须满足两个条件:

该类必须实现 java.io.Serializable 对象。

该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的。

如果你想知道一个Java标准类是否是可序列化的,请查看该类的文档。检验一个类的实例是否能序列化十分简单, 只需要查看该类有没有实现java.io.Serializable接口。


序列化对象

ObjectOutputStream 类用来序列化一个对象,如下的SerializeDemo例子实例化了一个Employee对象,并将该对象序列化到一个文件中。

该程序执行后,就创建了一个名为employee.ser文件。该程序没有任何输出,但是你可以通过代码研读来理解程序的作用。

注意: 当序列化一个对象到文件时, 按照Java的标准约定是给文件一个.ser扩展名。

import java.io.*;

public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}

反序列化对象

下面的DeserializeDemo程序实例了反序列化,/tmp/employee.ser存储了Employee对象。

import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}

以上程序编译运行结果如下所示:

Deserialized Employee...
Name: Reyan Ali
Address:Phokka Kuan, Ambehta Peer
SSN: 0
Number:101

这里要注意以下要点:

readObject() 方法中的try/catch代码块尝试捕获 ClassNotFoundException异常。对于JVM可以反序列化对象,它必须是能够找到字节码的类。如果JVM在反序列化对象的过程中找不到该类,则抛出一个 ClassNotFoundException异常。

注意,readObject()方法的返回值被转化成Employee引用。

当对象被序列化时,属性SSN的值为111222333,但是因为该属性是短暂的,该值没有被发送到输出流。所以反序列化后Employee对象的SSN属性为0。

Java - 29 Java 序列化的更多相关文章

  1. Java transient关键字序列化时使用小记

    1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过 ...

  2. Java对象的序列化和反序列化[转]

    Java基础学习总结--Java对象的序列化和反序列化 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化.把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用 ...

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

    原文地址:http://www.apkbus.com/forum.php?mod=viewthread&tid=13576&fromuid=3402 Java Serializable ...

  4. Java基础系列——序列化(一)

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6797659.html 工作中发现,自己对Java的了解还很片面,没有深入的研究,有很多的J ...

  5. 【Java基础】序列化与反序列化深入分析

    一.前言 复习Java基础知识点的序列化与反序列化过程,整理了如下学习笔记. 二.为什么需要序列化与反序列化 程序运行时,只要需要,对象可以一直存在,并且我们可以随时访问对象的一些状态信息,如果程序终 ...

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

    我对Java Serializable(序列化)的理解和总结 博客分类: Java技术 JavaOSSocketCC++  1.序列化是干什么的?       简单说就是为了保存在内存中的各种对象的状 ...

  7. java.io.Serializable 序列化问题

    java.io.Serializable 序列化问题 Person.java package a.b.c; public class Person implements java.io.Seriali ...

  8. java对象的序列化与反序列化使用

    1.Java序列化与反序列化  Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化与反序列化 我们知道,当两个进程进 ...

  9. 【Java】Java原生的序列化和反序列化

    写一个Java原生的序列化和反序列化的DEMO. 需序列化的类: package com.nicchagil.nativeserialize; import java.io.Serializable; ...

随机推荐

  1. ML(6)——改进机器学习算法

    现在我们要预测的是未来的房价,假设选择了回归模型,使用的损失函数是: 通过梯度下降或其它方法训练出了模型函数hθ(x),当使用hθ(x)预测新数据时,发现准确率非常低,此时如何处理? 在前面的章节中我 ...

  2. windows python监听文件触发脚本

    from watchdog.events import * class FileEventHandler(FileSystemEventHandler): def __init__(self): Fi ...

  3. linux应用之gcc环境的安装

    使用如下两个命令就可把gcc,gcc-c++统统安装 yum -y install gcc yum -y install gcc-c++ 但是用yum install gcc安装gcc编译环境,关于 ...

  4. dojo Datagrid 实现数据删除功能

    DataGrid实现数据动态刷新功能见前一个帖子:http://www.cnblogs.com/qq552048250/p/4447103.html 实现数据删除只需要向表格中动态添加按钮,并为按钮的 ...

  5. JS判断字符串是否为空或是否全为空格

    var test = " "; //为空或全部为空格 if (test.match(/^[ ]*$/)) { console.log("all space or empt ...

  6. java注解的自定义和使用

    小伙伴们.今天我们来说说注解.标志@ .针对java不同版本来说,注解的出现是在jdk1.5 但是在jdk1.5版本使用注解必须继续类的方法的重写,不能用于实现的接口中的方法实现,在jdk1.6环境下 ...

  7. PHP中的插件机制原理和实例

    PHP项目中很多用到插件的地方,更尤其是基础程序写成之后很多功能由第三方完善开发的时候,更能用到插件机制,现在说一下插件的实现.特点是无论你是否激活,都不影响主程序的运行,即使是删除也不会影响. 从一 ...

  8. NutzWk 开发框架

    官网: https://wizzer.cn/ 源码下载: https://github.com/wizzercn/NutzWk/ https://gitee.com/wizzer/NutzWk Int ...

  9. <亲测>CentOS7 安装mysql8.0(YUM方式)

    CentOS7 安装mysql(YUM方式)   1.下载mysql源安装包 shell> wget http://dev.mysql.com/get/mysql80-community-rel ...

  10. 引用 自动化测试基础篇--Selenium简介

    原文链接:http://www.cnblogs.com/sanzangTst/p/7452636.html 鸣谢参藏法师 一.软件开发的一般流程 二.什么叫软件测试? 软件测试(英语:Software ...