Java基础笔记 – 对象的序列化和反序列化及其实现和使用
本文由发表于6年前 | Java基础 | 暂无评论 |  被围观 6,903 views+
1、对象持久化:2、对象序列化(serialization):2.1、序列化说明:2.2、对象序列化的实现:2.3、ObjectOutput接口:2.3.1、基本方法:2.3.2、ObjectOutput接口的实现类ObjectOutputStream:2.3.3、ObjectOutputStream是一个过滤流,装饰了OutputStream,以下是其构造方法:2.4、ObjectInput接口:2.4.1、ObjectInput接口的实现类ObjectInputStream:2.4.2、基本方法:2.5、创建序列化对象并实现序列化和反序列化的例子:2.6、在序列化和反序列化过程中需要特殊处理的类必须使用下列准确签名来实现特殊方法:
1、对象持久化:

将一个对象保存到永久存储的设备上的机制。

2、对象序列化(serialization):

将对象转换为字节流保存起来是把一个对象的状态写入一个字节流的过程。在需要时还原此对象的机制。

在一个对象图表中,如果试图序列化一个顶层的对象,所有其他引用的对象都被循环的定位和序列化。同样,在反序列化过程中,所有的这些对象以及他们的引用都被正确恢复。

2.1、序列化说明:

当一个对象被序列化时,只保存对象的非静态成员变量。

如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。

如果一个可序列化的对象包含一个对象引用,而该引用的对象是不可序列化的,那么在序列化时会抛出NotSerializableException。可以使用标记transient该对象引用,设置该对象引用不被序列化,从而通过顶层对象的序列化。(声明为transient或static的变量不被序列化工具存储)

2.2、对象序列化的实现:

必须实现Serializable接口或者Externalizable接口。

public interface Serializable

类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

该接口是一个表示性接口,没有定义任何方法。当一个类实现了该接口时,就表示该类的对象是可以序列化的。

2.3、ObjectOutput接口:
public interface ObjectOutput
extends DataOutput

实现序列化。

ObjectOutput 扩展 DataOutput 接口以包含对象的写入操作。DataOutput 包括基本类型的输出方法;ObjectOutput 扩展了该接口,以包含对象、数组和 String 的输出方法。

2.3.1、基本方法:
void writeObject(Object obj)
                 throws IOException

将对象写入底层存储或流。实现此接口的类定义如何写入对象。

2.3.2、ObjectOutput接口的实现类ObjectOutputStream:
public class ObjectOutputStream
extends OutputStream
implements ObjectOutput, ObjectStreamConstants

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。

2.3.3、ObjectOutputStream是一个过滤流,装饰了OutputStream,以下是其构造方法:
protected ObjectOutputStream()
为完全重新实现 ObjectOutputStream 的子类提供一种方法,让它不必分配仅由 ObjectOutputStream 的实现使用的私有数据。
ObjectOutputStream(OutputStream out)
创建写入指定 OutputStream 的 ObjectOutputStream。

即是通过ObjectOutputStream的方法把对象写出到OutputStream字节流中。

2.4、ObjectInput接口:
public interface ObjectInput
extends DataInput

实现反序列化。

ObjectInput 扩展 DataInput 接口以包含对象的读操作。DataInput 包括基本类型的输入方法;ObjectInput 扩展了该接口,以包含对象、数组和 String 的输出方法。

2.4.1、ObjectInput接口的实现类ObjectInputStream:
public class ObjectInputStream
extends InputStream
implements ObjectInput, ObjectStreamConstants

ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。

ObjectInputStream也是一个过滤流。

2.4.2、基本方法:
public final Object readObject()
                        throws IOException,
                               ClassNotFoundException

从 ObjectInputStream 读取对象。对象的类、类的签名和类及所有其超类型的非瞬态和非静态字段的值都将被读取。可以使用 writeObject 和 readObject 方法为类重写默认的反序列化。由此对象引用的对象是可传递读取的,这样 readObject 即可重新构造这些对象的完全等价的图形。

2.5、创建序列化对象并实现序列化和反序列化的例子:

创建序列化对象:

/**
 * 创建序列化对象
 */
class User implements Serializable{

    private static final long serialVersionUID = 1L;
    //transient关键字,不被序列化
    transient String username;
    String password;
    public User(String username, String password){
        this.username = username;
        this.password = password;
    }
}

通过ObjectOutputStream和ObjectInputStream的方法实现序列化和反序列化:

public static void main(String[] args) throws IOException, ClassNotFoundException {

    //以下是实现对象序列化
    //创建序列化对象
    User user = new User("arthinking", "arthinking");
    //创建文件字节输出流
    FileOutputStream fos = new FileOutputStream("D:/itzhai/arthinking.txt");
    //通过文件字节输出流构造对象输出流
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    //写出对象
    oos.writeObject(user);
    oos.close();

    //以下是实现对象反序列化
    FileInputStream fis = new FileInputStream("D:/itzhai/arthinking.txt");
    ObjectInputStream ois = new ObjectInputStream(fis);
    //不会调用任何构造方法,而是根据反序列化出来的对象状态信息构造对象
    User user2 = (User) ois.readObject();
    //username不被序列化,这里输出为null
    System.out.println(user2.username);
    System.out.println(user2.password);
}
2.6、在序列化和反序列化过程中需要特殊处理的类必须使用下列准确签名来实现特殊方法:
 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData()
     throws ObjectStreamException;

例如上面例子中的User类如果实现了这两个方法,那么在使用ObjectOutputStream的writeObject()方法输出对象时,就不会自动序列化对象,而是执行这里的writeObject方法,在这两个方法中可以使用ObjectOutputStream和ObjectInputStream的一些方法对对象的属性进行序列化,如:

oos.writeUTF(username)
除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/java-based-notebook-object-serialization-and-deserialization-of-its-implementation-and-use-of.html
arthinking Java技术交流群:280755654,入门群:428693174 more
分享到:
 
2011 10/23
文章评论
    没有评论
给我留言

有人回复时邮件通知我
Java基础的相关文章
随机文章 本月热门 热评
1 Javascript中的for in语句获取对象属性的顺序问题 2012/8/16
2 JSF笔记 – MVC和JSF的介绍和下载使用 2011/12/1
3 Java Web笔记 – Sessoin的使用 2011/11/12
4 NodeJS学习笔记 – 入门简介 2013/10/9
5 Spring与Struts2整合的两种解决方案 2011/5/23
6 C语言语法笔记汇总 | IT宅文章归档 AD 2011/11/14 2011/11/14
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
Mr.5's Life 白天是一名程序员,晚上就是个有抱负的探索者
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.