天天看点

java对象序列化的概念和实现

一 序列化的概念和实现方法

序列化的概念就是把一个object直接转换成为byte流写到硬盘或者通过网络进行传播。java序列化技术可以将一个对象的状态写入一个byte流里,并且可以从其它地方把该byte流里的数据读出来,重新构造一个相同的对象。这种机制允许将对象通过网络进行传播,并可以随时把对象持久化到数据库、文件等系统里。java的序列化机制是rmi、ejb等技术的技术基础。

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象 传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

序列化的实现——将需要被序列化的类实现serializable接口,根据需求读出或者写入对象。在web开发中,如果对象被保存在了session中,tomcat在重启时要把session对象序列化到硬盘,这个对象就必须实现serializable接口。如果对象要经过分布式系统进行网络传输或通过rmi等远程调用,这就需要在网络上传输对象,被传输的对象就必须实现serializable接口。

看例子

import java.io.file;

import java.io.fileinputstream;

import java.io.fileoutputstream;

import java.io.ioexception;

import java.io.objectinputstream;

import java.io.objectoutputstream;

import java.io.serializable;

import java.net.urisyntaxexception;

import cn.test.fileinputandoutputstream;

public class objectio

{

 // 将对象写入文件

 public static void output(string path)

 {

  student s = new student();

  s.num = 2;

  s.name = "xy2";

  s.address = "goodplace2";

  s.wifename = "nobody2";

  file f = new file(path);

  fileoutputstream fout = null;

  objectoutputstream bout = null;

  try

  {

   fout = new fileoutputstream(f);

   bout = new objectoutputstream(fout);

   bout.writeobject(s);

   bout.flush();

   bout.close();

  }

  catch (ioexception e)

   e.printstacktrace();

 }

 // 将写入的对象读出

 public static void input(string path)

  fileinputstream fin = null;

  objectinputstream bin = null;

   fin = new fileinputstream(f);

   bin = new objectinputstream(fin);

   student s = (student) bin.readobject();

   system.out.println(s.num + "..." + s.name + "..." + s.address + "..." + s.wifename);

  catch (exception e)

 // writeobject和readobject是线程安全的,传输过程中不允许被并发访问,故对象能不断传来

 public static void main(string[] args) throws urisyntaxexception

  string path = fileinputandoutputstream.class.getclassloader().getresource("对象文档.txt").touri().getpath();

  output(path);

  input(path);

}

@suppresswarnings("serial")

class student implements serializable

 int num = 1;

 string name = "xy";

 string address = "goodplace";

 transient string wifename = "nobody";

二 序列化的注意点

注意点1

如果某个类能够被序列化,其子类也可以被序列化。如果该类有父类,则分两种情况来考虑,如果该父类已经实现了可序列化接口。 则其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现可序列化接口,则该类的父类所有的字段属性将不会序列化。

注意点2

声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,transient代表对象的临时数据。

注意点3

在java.io包提供的涉及对象的序列化的类与接口有

objectoutput接口

该接口继承dataoutput接口并支持对象的序列化,其writeobject()方法实现存储一个对象。

objectinput接口

该接口继承datainput接口并支持对象的序列化,其readobject()方法实现读取一个对象。

objectoutputstream类

该类继承outputstream类并实现objectoutput接口,可调用接口中的writeobject方法。

objectinputstream类。

该类继承inputstream类并实现objectinput接口,可调用接口中的readobject方法。

注意点4

对于父类的处理时,若父类没有实现序列化接口,则其必须有默认的构造函数,否则编译的时候就会报错。在反序列化的时候,默认构造函数会被调用。若把父类标记为可以序列化,则在反序列化的时候,其默认构造函数不会被调用。因为java对序列化的对象进行反序列化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成。

参考博客:http://blog.csdn.net/yakihappy/article/details/3979373