疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

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


 

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

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

用途是利用对象的序列化实现保存应用程序的当前工作状态,下次再启动时将自动地恢复到上次执行的状态,例如游戏的存盘。

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

序列化的实现--将需要被序列化的类实现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)

{

File f = new File(path);

FileInputStream fin = null;

ObjectInputStream bin = null;

try

{

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)

{

e.printStackTrace();

}

}

// 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对序列化的对象进行反序列化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成