Java中对象的序列化

简单的说,是对对象进行序列化的处理,以流的形式进行传输。其目的是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来。

Java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的“深复制”,即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。


实现对象的序列化非常简单,只需对象实现了Serializable接口即可(该接口仅是一个标记,没有方法)。在Java  1.1中,许多标准库类都发生了改变,以便能够序列化——其中包括用于基本数据类型的全部封装器、所有集合类以及其他许多东西。甚至Class对象也可以序列化。   

序列化一个对象的步骤:

1.首先要创建某些OutputStream对象

2.然后将其封装到ObjectOutputStream对象内。

3.用ObjectOutputStream的对象调用writeObject()用于实现存储一个对象完成了对对象的序列化


4.创建InputStream对象

5.将其封装到ObjectInputStream对象内

6.用ObjectInputStream的对象调用readObject()用于实现读取一个对象


说了这么多,来看一个例子。一道题目:

定义一个信息类(Information),将由10个信息对象组成的链表(可直接使用java集合类)写入d:\\1.ser中,然后再从文件中读回这10个对象,并在屏幕上输出来,要求用对象序列化实现。


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package information;
import java.io.*;
import java.util.*;
/**
 *
 * @author Soledad
 */
public class Information {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        List<Inf> list =new LinkedList<Inf>();
        list.add(new Inf("abc"));
        list.add(new Inf("def"));
        list.add(new Inf("ghi"));
        list.add(new Inf("jkl"));
        list.add(new Inf("mno"));
        list.add(new Inf("pqr"));
        list.add(new Inf("stu"));
        list.add(new Inf("vwx"));
        list.add(new Inf("yza"));
        list.add(new Inf("bcd"));
        try {
            OutputStream os = new FileOutputStream("d:\\1.ser");//创建OutputStream对象
            ObjectOutputStream oos = new ObjectOutputStream(os);//封装到ObjectOutputStream内
            oos.writeObject(list);//调用writeObject()函数
            oos.flush();
        
            InputStream is = new FileInputStream("d:\\1.ser");//创建InputStream对象
            ObjectInputStream ois = new ObjectInputStream(is);//封装到ObjectInputStream内
            List<Inf> l=(LinkedList<Inf>)ois.readObject();//调用readObject()函数
        for(int i=0;i<10;i++)
        {
            Inf inf = l.get(i);
            System.out.println(inf.getString());
        }
        
        // TODO code application logic here
    }
        catch(Exception e){
            e.printStackTrace();
        }
}
}
//Inf对象实现Serializable接口
class Inf implements Serializable{
    private String str;
    public String getString(){
    return str;
            }
    public Inf(String s)
    {str=s;
    }
}

代码里30~37行即为实现序列化操作的步骤。

在代码的最后对Inf对象实现了Serializable接口。


这样子,对象的序列化就大功告成了。

需要注意的几点事项

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

(2)声明为static和transient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据;

(3)对于父类的处理,如果父类没有实现串行化接口,则其必须有默认的构造函数(即没有参数的构造函数)。否则编译的时候就会报错。在反串行化的时候,默认构造函数会被调用。但是若把父类标记为可以串行化,则在反串行化的时候,其默认构造函数不会被调用。这是为什么呢?这是因为Java 对串行化的对象进行反串行化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成。


另外,writeObject和readObject本身就是线程安全的,传输过程中是不允许被并发访问的。所以先不用担心线程冲突的问题。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值