Java 序列化机制

Java 的对象序列化将那些实现了Serializable 接口的对象转换成一个字节序列, 并能够在以后将这个字节序列完全恢复为原来的对象. 这一过程可以在网络进行, 这意味着序列化机制能自动弥补不同操作系统之间的差异.

对象序列化的概念是RMI,EJB 等技术的基础.

很多标准类库都实现了序列化机制, 包括所有的基础数据类型的封装器, 所有容器类以及很多其他的东西. 甚至Class 对象也可以被序列化.

 

序列化与反序列化的方法:

要序列化一个对象A, 首先要创建ObjectInputStream 对象, 然后writeObject 对象A, 恢复对象A 的时候创建ObjectOutputStream 对象, 然后readObject 得到对象A.

 

Serializable 对象来说, 对象完全以它存储的二进制位为基础来构造, 而不是调用构造器. 而对于一个Externalizable 对象, 恢复对象的时候, 所有普通的默认构造器都会被调用, 然后再调用readExternal().

Externalizable 接口:

实例: 该接口中有两个方法, 在序列化与反序列化的时候使用, 而不是调用ObjectInputStreamObjectOutputStream 中的方法.

 

清单1: User

import java.io.Externalizable;

import java.io.IOException;

import java.io.ObjectInput;

import java.io.ObjectOutput;

 

public class User implements Externalizable

{

    private static final long serialVersionUID = 1L;

 

    private int id ;

 

    private String name ;

 

    private String password ;

 

    public User()

    {

        System. out .println( " 默认构造方法" );

    }

 

    public User( int id, String name, String password)

    {

        this . id = id;

        this . name = name;

        this . password = password;

        System. out .println( " 有参构造方法" );

    }

 

    public int getId()

    {

        return id ;

    }

 

    public void setId( int id)

    {

        this . id = id;

    }

 

    public String getName()

    {

        return name ;

    }

 

    public void setName(String name)

    {

        this . name = name;

    }

 

    public String getPassword()

    {

        return password ;

    }

 

    public void setPassword(String password)

    {

        this . password = password;

    }

 

    public void readExternal(ObjectInput objectInput) throws IOException,

            ClassNotFoundException

    {

        System. out .println( "" );

        id = (Integer) objectInput.readObject();

        name = (String)objectInput.readObject();

        password = (String)objectInput.readObject();

    }

 

    public void writeExternal(ObjectOutput objectOutput) throws IOException

    {

        System. out .println( "" );

        System. out .println( id );

        objectOutput.writeObject( id );

        objectOutput.writeObject( name );

        objectOutput.writeObject( password );

    }

}

 

要序列化的对象一定要确保自己的父类能够建立成功, 即父类有无参构造方法.

 

Transient 关键字

对于一个serializable 来说, 如果不想让某个字段进行序列化的话, 则对该字段加上Transient, 则该字段不会序列化.

由于Externalizable 对象在默认情况下不保存他们的任何字段, 所以Transient 关键字只能和Serializable 对象一起使用.

 

Externalizable 的替代方法( 最好的方法)

在实现serializable 接口的对象中, 添加writeObject()readObject() 方法.

这样一旦对象被序列化或者反序列化还原, 就会自动的分别调用这两个方法, 只要提供这两个方法, 就会使用他们而不是默认的序列化机制.

这些方法必须有准确的方法特征签名:

private void readObject(ObjectInputStream objectInput) throws IOException,

            ClassNotFoundException

    {

        objectInput.defaultReadObject();

    }

 

    private void writeObject(ObjectOutputStream objectOutput) throws IOException

    {

        objectOutput.defaultWriteObject();

    } 在调用ObjectOutputStream.writeObject(), 会检查所传递的Serializable 对象, 看看是否实现了自己的writeObject(), 如果是这样, 就跳过正常的序列化过程并调用它的witeObject

在自己的writeObject(), 我们可以调用defaultWriteObject 方法来执行默认的witeObject(), 就是执行序列化机制.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值