`
toprogrammer
  • 浏览: 64555 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java:序列化(转)

阅读更多
下面和大家分享的是java序列化的一些基础知识,希望能够带给大家帮助。

1 Java 序列化技术概述

Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方

把该Byte 流里的数据读出来。重新构造一个相同的对象。这种机制允许你将对象通过网络

进行传播,并可以随时把对象持久化到数据库、文件等系统里。Java的序列化机制是RMI、

EJB、JNNI等技术的技术基础。

1.1 序列化技术基础

并非所有的Java 类都可以序列化,为了使你指定的类可以实现序列化,你必须使该类

实现如下接口:

java.io.Serializable

需要注意的是,该接口什么方法也没有。实现该类只是简单的标记你的类准备支持序列

化功能。我们来看如下的代码:

/**

* 抽象基本类,完成一些基本的定义

*/

public abstract class Humanoid

{

protected int noOfHeads;

private static int totalHeads;

public Humanoid()

{

this(1);

}

public Humanoid(int noOfHeads)

{

如何正确的使用Java序列化技术 技术研究系列

if (noOfHeads > 10)

throw new Error("Be serious. More than 10 heads?!");

this.noOfHeads = noOfHeads;

synchronized (Humanoid.class)

{

totalHeads += noOfHeads;

}

}

public int getHeadCount()

{

return totalHeads;

}

}

该类的一个子类如下:

/**

* Humanoid的实现类,实现了序列化接口

*/

import java.io.*;

public class Person extends Humanoid

implements java.io.Serializable

{

private String lastName;

private String firstName;

private transient Thread workerThread;

private static int population;

public Person(String lastName, String firstName)

{

this.lastName = lastName;

this.firstName = firstName;

synchronized (Person.class)

{

population++;

}

}

public String toString()

{

return "Person " + firstName + " " + lastName;

}

static synchronized public int getPopulation()

{

return population;

}

}

1.2 对象的序列化及反序列化

上面的类Person 类实现了Serializable 接口,因此是可以序列化的。我们如果要把一个

可以序列化的对象序列化到文件里或者数据库里,需要下面的类的支持:

java.io.ObjectOutputStream

如何正确的使用Java序列化技术 技术研究系列

下面的代码负责完成Person类的序列化操作:

/**

* Person的序列化类,通过该类把Person写入文件系统里。

*/

import java.io.*;

public class WriteInstance

{

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

{

if (args.length != 1)

{

System.out.println("usage: java WriteInstance file");

System.exit(-1);

}

FileOutputStream fos = new FileOutputStream(args[0]);

ObjectOutputStream oos = new ObjectOutputStream(fos);

Person p = new Person("gaoyanbing", "haiger");

oos.writeObject(p);

}

}

如果我们要序列化的类其实是不能序列化的,则对其进行序列化时会抛出下面的异常:

java.io.NotSerializableException

当我们把Person 序列化到一个文件里以后,如果需要从文件中恢复Person 这个对象,

我们需要借助如下的类:

java.io.ObjectInputStream

从文件里把Person类反序列化的代码实现如下:

/**

* Person的反序列化类,通过该类从文件系统中读出序列化的数据,并构造一个

* Person对象。

*/

import java.io.*;

public class ReadInstance

{

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

{

if (args.length != 1)

{

System.out.println("usage: java ReadInstance filename");

System.exit(-1);

}

FileInputStream fis = new FileInputStream(args[0]);

ObjectInputStream ois = new ObjectInputStream(fis);

Object o = ois.readObject();

如何正确的使用Java序列化技术 技术研究系列

System.out.println("read object " + o);

}

}

1.3 序列化对类的处理原则

并不是一个实现了序列化接口的类的所有字段及属性都是可以序列化的。我们分为以下

几个部分来说明:

u 如果该类有父类,则分两种情况来考虑,如果该父类已经实现了可序列化接口。则

其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现可序列化接

口,则该类的父类所有的字段属性将不会序列化。

u 如果该类的某个属性标识为static类型的,则该属性不能序列化;

u 如果该类的某个属性采用transient关键字标识,则该属性不能序列化;

需要注意的是,在我们标注一个类可以序列化的时候,其以下属性应该设置为transient

来避免序列化:

u 线程相关的属性;

u 需要访问IO、本地资源、网络资源等的属性;

u 没有实现可序列化接口的属性;(注:如果一个属性没有实现可序列化,而我们又

没有将其用transient 标识, 则在对象序列化的时候, 会抛出

java.io.NotSerializableException 异常)。

1.4 构造函数和序列化

对于父类
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics