`
wangqisen
  • 浏览: 47270 次
文章分类
社区版块
存档分类
最新评论

对象的序列化和反序列化及其实现和使用

阅读更多

对象的序列化和反序列化及其实现和使用


1、对象持久化:

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

2、对象序列化(serialization):

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

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

2.1、序列化说明:

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

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

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

2.2、对象序列化的实现:

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

public interface Serializable

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

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

2.3、ObjectOutput接口:
public interfaceObjectOutput
extends DataOutput

实现序列化。

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

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

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

2.3.2、ObjectOutput接口的实现类ObjectOutputStream:
public classObjectOutputStream
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 interfaceObjectInput
extends DataInput

实现反序列化。

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

2.4.1、ObjectInput接口的实现类ObjectInputStream:
public classObjectInputStream
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)

分享到:
评论

相关推荐

    Android对象序列化的代码例子

    Android对象序列化的代码例子。用于演示Parcelable和Serializable两种结构的序列化对象,及其使用时的注意点。

    grpc-node-status-proto:使用 grpc 时序列化和反序列化“grpc-status-details-bin”元数据的库

    使用包时,用于在grpc-status-details-bin元数据值和 StatusProto 之间进行序列化和反序列化的实用函数。 错误详细信息允许发送/接收附加数据以及错误。 例如,如果请求发送无效数据,gRPC 服务器可以发回一条消息...

    YAXLib:.NET Framework和.NET Core的另一个XML序列化库

    YAXLib是一个灵活的XML序列化库,它使开发人员可以自由设计XML文件结构,在要序列化的私有字段和公共字段中进行选择,并序列化序列中所有已知的集合类和数组(单维,多维和锯齿状数组)。 .NET Framework。 YAXLib...

    msgpack:MessagePack是一个非常高效的对象序列化库。 就像JSON,但是非常小巧

    消息包MessagePack是一种有效的二进制序列化格式。 就像JSON。 但又快又小。 该存储库管理MessagePack格式的规范。 有关,请参见。 实施项目都有各自的存储库。 请访问网站以查找实现及其文档。 如果您想在网站上...

    Sql Serializable Java Object Generator:用于生成序列化到MySQL的Java对象的程序-开源

    定义对象及其关系后,您可以将它们序列化为java类,该类将自动序列化和反序列化为MySQL。 此输出可用于加快将数据持久存储在数据库中的程序的开发。 该程序有一天可能会扩展到涵盖其他语言和数据库。

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    第23章 管理Session和实现对话  23.1 管理Session对象的生命周期  23.1.1 Session对象的生命周期与本地线程绑定  23.1.2 Session对象的生命周期与JTA事务绑定  23.2 实现对话  23.2.1 使用游离对象  23.2.2 ...

    gson-2.8.6.jar下载

    3. 支持用户自定义序列化和反序列化的规则。可以直接将gson和bean-validation框架结合,校验Java对象的字段。 4. 支持基本数据类型及其封装类型,Collection类型,Date类型及自定义类型。 5. 支持将JSON数组转换为Java...

    2023Java高频面试题

    IO流:Java中常用的文件读写、序列化和反序列化等操作。 多线程编程:线程的基本概念、线程同步、线程安全、死锁等问题。 JDBC:Java与数据库的交互,连接池的使用等。 Spring框架:Spring框架的基础概念、IOC容器、...

    javabean-marshaller:将对象图序列化为其Java代码

    代替使用XML或JSON序列化,将数据集生成为Java语言。 此格式更适合于性能和重构目的。 技术支持 基本类型及其包装器类 枚举 馆藏与地图 数组(1维和2维) java.util.Date,java.sql.Date,日历,...

    CLR.via.C#.(中文第3版)(自制详细书签)Part2

    10.1.3 对象和集合初始化器 10.1.4 匿名类型 10.1.5 System.Tuple类型 10.2 有参属性 10.3 调用属性访问器方法时的性能 10.4 属性访问器的可访问性 10.5 泛型属性访问器方法 第11章 事件 11.1 设计要公开...

    pepper-box:Pepper-Box是jmeter的kafka负载生成器插件。 它允许发送纯文本(JSON,XML,CSV或任何其他自定义格式)类型的kafka消息以及Java序列化的对象

    Pepper-Box序列化配置:此jmeter config元素根据输入类及其属性配置生成序列化的对象消息。 PepperBoxLoadGenerator :这是独立的实用程序,无需使用jmeter即可使用。 设置 要求 Pepper-Box使用带有Java编译器API...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    10.1.3 对象和集合初始化器 10.1.4 匿名类型 10.1.5 System.Tuple类型 10.2 有参属性 10.3 调用属性访问器方法时的性能 10.4 属性访问器的可访问性 10.5 泛型属性访问器方法 第11章 事件 11.1 设计要公开...

    CLR.via.C#.(中文第3版)(自制详细书签)

    24.9 反序列化对象时重写程序集和/或类型 第25章 线程基础 25.1 Windows为什么要支持线程 25.2 线程开销 25.3 停止疯狂 25.4 CPU发展趋势 25.5 NUMA架构的机器 25.6 CLR线程和Windows线程 25.7 使用专用线程...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    10.1.3 对象和集合初始化器 10.1.4 匿名类型 10.1.5 System.Tuple类型 10.2 有参属性 10.3 调用属性访问器方法时的性能 10.4 属性访问器的可访问性 10.5 泛型属性访问器方法 第11章 事件 11.1 设计要公开...

    jsonapi-serializers:JSON的纯Ruby只读序列化器

    根链接根错误根jsonapi对象明确的序列化程序发现命名空间序列化器稀疏字段集人际关系复合文件,包括关系路径处理控制关系中的链接和数据仪器仪表Rails的例子Sinatra范例未完成的事贡献 特征可与任何Ruby Web框架...

    精通MFC (光盘) 源代码

    4.6.3 对象序列化实例 4.7 小结 第5章 MFC应用框架 5.1 应用程序对象和MFC类库的交互 5.2 应用程序的初始化 5.3 消息循环 5.4 空闲处理 5.5 应用程序的退出 5.6 CWinApp提供的其他服务 5.6.1 外壳程序注册...

    Java大数据开发+Java大厂面试题

    什么是Java的序列化和反序列化?为什么它们在分布式系统中很重要? 解释什么是Java的设计模式,并列举几个常用的设计模式及其应用场景。 这些题目涵盖了Java开发中的核心概念和常见问题,帮助您准备面试。祝您面试...

    Java后端+Java后端中级面试题

    什么是Java的序列化和反序列化?为什么它们在分布式系统中很重要? 解释什么是Java的设计模式,并列举几个常用的设计模式及其应用场景。 这些题目涵盖了Java开发中的核心概念和常见问题,帮助您准备面试。祝您面试...

    Java面试题+Java后端中级面试题

    什么是Java的序列化和反序列化?为什么它们在分布式系统中很重要? 解释什么是Java的设计模式,并列举几个常用的设计模式及其应用场景。 这些题目涵盖了Java开发中的核心概念和常见问题,帮助您准备面试。祝您面试...

Global site tag (gtag.js) - Google Analytics