Java中的序列化

以下内容引用自http://wiki.jikexueyuan.com/project/java/serialization.html

Java提供了一种机制,叫做对象序列化,这里对象被描述成一系列包括对象的数据以及有关对象的类型和在对象中存储的数据的类型的字节。

在一个序列化的对象被写进文件之后,它能在文件中被读出并被反序列化为类型信息和表示对象的字节,并且它的数据可以被用来重新创建在内存中的对象。

最让人印象深刻的是整个过程是JVM独立的,意味着一个对象能在一个平台上序列化,并能在在一个完全不同的平台上被反序列化。

ObjectInputStream和ObjectOutputStream类是包含序列化和反序列化对象的方法的流。

ObjectOutputStream类含有许多写各种各样数据类型的写方法,但是其中一个方法尤其突出:

public final void writeObject(Object x) throws IOException

上述的方法序列化了一个对象并将它送入输出流。相同的,ObjectInputStream类包含以下反序列化对象的方法:

public final Object readObject() throws IOException,  ClassNotFoundException

这个方法检索流之外的下一个对象并且反序列化之。返回值是对象,所以需要将它转换成正确的数据类型。

为了论证序列化在Java中是如何工作的,使用之前的Employee类。假设有以下的实现Serializable的Employee类:

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程序反序列化了一个在SerializeDemo对象中被创建的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

下面是一些需要注意的要点:

  • try/catch块试图抓住readObject()方法声明的ClassNotFoundException。为了使一个JVM能反序列化一个对象,它必须能找到类的字节代码。如果JVM在一个对象的反序列化过程中不能找到一个类,它将抛出ClassNotFoundException。
  • 注意readObject()的返回值将被强制类型转换为Employee的引用。
  • 当对象被序列化时SSN字段的值是11122333,但是因为字段是短暂的,值没有送入输出流。反序列化的Employee对象的SSN字段值是0。

测试工程:https://github.com/easonjim/5_java_example/tree/master/javabasicstest/test25

时间: 2024-10-15 01:28:29

Java中的序列化的相关文章

Java中如何序列化一个对象(转)

转自:http://blog.csdn.net/chx10051413/article/details/40784667 http://www.cnblogs.com/baoendemao/p/3804797.html Java 中如何序列化一个对象 我们都知道java 中无法保存一个对象到文本文件中,但是当我们有这种需求的时候,我们可以通过java 的序列化功能把当前对象的一些属性以二进制的形式保存到文件中.当我们需要这个对象的时,只需要从二进制文件中还原为保存前的对象即可.从这里我们可以得到

面试题:Java中对象序列化接口(Serializable)的意义

Serializable接口是一个里面什么都没有的接口 它的源代码是public interface Serializable{},即什么都没有. 如果一个接口里面什么内容都没有,那么这个接口是一个标识接口,比如,一个学生遇到一个问题,排错排了几天也没解决,此时,她举手了(示意我去帮他解决),然后我过去,帮他解决了,那么这个举手其实就是一个标识,自己不能解决的问题标示我去帮他解决,在Java中的这个Serializable接口是给JVM看的,告诉JVM,我不做这个类的序列化了,你(JVM)给我序

java中的序列化与反序列化,还包括将多个对象序列化到一个文件中

package Serialize; /** * Created by hu on 2015/11/7. *///实现序列化必须实现的接口,这就是一个空接口,起到标识的作用import java.io.Serializable; /** * 用来进行序列化和反序列化的类 * */public class person implements Serializable { private int age; private String name; private String sex; public

java中的序列化和反序列化学习笔记

需要序列化的Person类: package cn.itcast_07; import java.io.Serializable; /* * NotSerializableException:未序列化异常 * * 类通过实现 java.io.Serializable 接口以启用其序列化功能.未实现此接口的类将无法使其任何状态序列化或反序列化. * 该接口居然没有任何方法,类似于这种没有方法的接口被称为标记接口. * * java.io.InvalidClassException: * cn.it

java中的序列化问题

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是为了解决在对对象流进行读写操作时所引发的问题. 序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个Object

在Java中进行序列化和反序列化

对象序列化的目标是将对象保存在磁盘中,或者允许在网络中直接传输对象. 对象序列化允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上或者通过网络将这种二进制流传输到另外一个网络节点. 其他程序一旦获得了这种二进制流,都可以将这种二进制流恢复成原本的Java对象. 序列化的含义和意义 序列化机制允许将实现序列化的Java对象转换成字节序列,这些字节序列可以进行持久化或者通过网络传输,使得对象可以脱离程序的运行而独立存在. 序列化将一个Java对象写入IO流中.

java中的序列化流和反序列化流

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px SimSun; color: #4e9072 } 序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输.  对象 -- 流数据(ObjectOutputStream) 反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象.流数据 -- 对象(ObjectInputStream) 序列化流和反序列化流不同于字节流 字符流 内存字节流,这些都是把字符串写入/读取文件,序列

Java中实现序列化的两种方式 Serializable 接口和 Externalizable接口

方法一: 实现Serializable接口,这个我就不多说了 方法二: 实现Externalizable接口: 例子: package demo; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; public class XXS implements Externalizable{ private String n

[转]java 中的序列化是什么意思?有什么好处?

1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化. 2.什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候: b)当你想用套接字在网络上传送对象的时候: c)当你想通过RMI传输对象的时候: 3.当对一个对象实现序列化时,究竟发生了什么? 在没有序列化前,每个保存在堆(Hea