一、序列化和反序列化的概念
  把对象转换为字节序列的过程称为对象的序列化。
  把字节序列恢复为对象的过程称为对象的反序列化。
  对象的序列化主要有两种用途:
  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  2) 在网络上传送对象的字节序列。
  在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
  当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

一个对象要想能够实现序列化,必须实现Serializable接口或Externalizable接口。,该接口中没有定义任何方法,是一个标识性接口( Marker Interface),当一个类实现了该接口,就表示这个类的对象是可以序列化的。

• 当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
• 如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
• 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化

在序列化时, static 变量是无法序列化的;如果 A 包含了对 B 的引用,那么在序列化A 的时候也会将 B 一并地序列化;如果此时 A 可以序列化, B 无法序列化,那么当序列化 A 的时候就会发生异常,这时就需要将对 B 的引用设为 transient,该关键字表示变量不会被序列化。

二、JDK类库中的序列化API
  java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
  java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
  只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以 采用默认的序列化方式 。
  对象序列化包括如下步骤:
  1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
  2) 通过对象输出流的writeObject()方法写对象。
  对象反序列化的步骤如下:
  1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
  2) 通过对象输入流的readObject()方法读取对象。

对象序列化和反序列范例:

public class Person implements Serializable {

    private String name;
private int age;
private double height; public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public double getHeight() {
return height;
} public void setHeight(double height) {
this.height = height;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

序列化和反序列化Person类对象

public class TestObjSerializeAndDeserialize {

    public static void main(String[] args) throws Exception {

        //序列化Person对象
serializePerson(); //反序列化Person对象
Person person = deserializePerson(); System.out.println(person.getName() + "," + person.getAge() + "," + person.getHeight());
} private static void serializePerson() throws Exception {
Person person1 = new Person();
person1.setName("zhangsan");
person1.setAge(20);
person1.setHeight(170.1); // ObjectOutputStream 对象输出流,将Person对象存储到C盘的Person.txt文件中,
// 完成对Person对象的序列化操作
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(
new File("c:\\person.txt")));
oos.writeObject(person1);
oos.close();
} private static Person deserializePerson() throws Exception {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(
new File("c:\\person.txt")));
Person person = (Person) ois.readObject(); return person;
}
}

序列化Person成功后在C盘生成了一个Person.txt文件,而反序列化Person是读取E盘的Person.txt后生成了一个Person对象

Java IO5:序列化与反序列化的更多相关文章

  1. java 对象序列化与反序列化

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

  2. Java对象序列化与反序列化一 JSON

    Java对象序列化与反序列化一 JSON 1. 依赖库 jackson-all-1.6.1.jar 2. 代码 public class Student {    private String nam ...

  3. Java对象序列化和反序列化的工具方法

    import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...

  4. Java之序列化和反序列化

    序列化的对象: package test_demo.SerializableOper; import java.io.Serializable; /* * 序列化对象需要实现序列号接口 * */ pu ...

  5. java之序列化与反序列化

    1.这里主要是介绍Protobuf提供的序列化与反序列化的高效性.相对于传统的java提供的序列化来说,Protobuf的效率提高了很多倍.但是也有不足的地方,就是proto在对象序列化的时候抛弃了很 ...

  6. Java基础—序列化与反序列化(转载)

    转载自: Java序列化与反序列化 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化 ...

  7. Java 中序列化与反序列化

    一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...

  8. JAVA的序列化与反序列化

    一.为什么要进行序列化 再介绍之前,我们有必要先了解下对象的生命周期,我们知道Java对象的生命周期,也即Java中的远程方法调用RMI也会被用到,在网络中要传输对象的话,则必须要对对象进行序列化,关 ...

  9. 深入分析Java的序列化与反序列化

    序列化是一种对象持久化的手段.普遍应用在网络传输.RMI等场景中.本文通过分析ArrayList的序列化来介绍Java序列化的相关内容.主要涉及到以下几个问题: 怎么实现Java的序列化 为什么实现了 ...

  10. Java 对象序列化和反序列化

         之前的文章中我们介绍过有关字节流字符流的使用,当时我们对于将一个对象输出到流中的操作,使用DataOutputStream流将该对象中的每个属性值逐个输出到流中,读出时相反.在我们看来这种行 ...

随机推荐

  1. dorado问题查询&快捷键重命名

    重命名还有一个快捷键  F2 有关dorado的问题可以进 www.bsdn.org提问,而且更好

  2. poj 3616 Milking Time

                                                                                                 Milking ...

  3. lex&yacc8--wehter use in C++

    bintree.h:12:1: error: unknown type name ‘using’ using namespace std; ============== bintree.h:28:1: ...

  4. python mysqldb使用dictcursor

    python在使用MySQLdb库的时候,如下方法默认获取的cursor的结果集是tuple结构的. con = MySQLdb.connect('host',port,'username','pas ...

  5. alter和alert的一些问题

    今天在Java学习群里看到有人问:用alert能不能修改表结构?我第一反应是,alert是弹窗啊,怎么修改表结构?后来再看才知道,是那人打错了!我也晕了一下,还是记一下吧!alter是修改表结构的,a ...

  6. input内容改变触发事件,兼容IE

    <html> <head> <script type="text/javascript"> window.onload = function() ...

  7. ng-src作用

    ... <ul class="phones"> <li ng-repeat="phone in $ctrl.phones | filter:$ctrl. ...

  8. FileStream使用小记

    流用于对IO处理 在System.IO名称空间中有以下类 BinaryReader/Writer TextReader/Writer Stream 其中类Stream为抽象类.由此有三个派生类: Me ...

  9. Qt模拟C#的File类对文件进行操作

    其实只是QT菜鸟为了练习而搞出来的 文件头: #include <QFile> #include <QString> #include <iostream> #in ...

  10. C# 在运行时动态创建类型

    C# 在运行时动态的创建类型,这里是通过动态生成C#源代码,然后通过编译器编译成程序集的方式实现动态创建类型 public static Assembly NewAssembly() { //创建编译 ...