一、ObjectOutputStream
- ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream
- 可以使用 ObjectInputStream 读取(重构)对象。
- 通过在流中使用文件可以实现对象的持久存储。
- 如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
- 只能将支持 java.io.Serializable 接口的对象写入流中。
- 每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包
public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants { //创建写入指定 OutputStream 的 ObjectOutputStream public ObjectOutputStream(OutputStream out) throws IOException{} //将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入。 public final void writeObject(Object obj) throws IOException{} //以 UTF-8 修改版格式写入此 String 的基本数据。 //注意,将 String 作为基本数据写入流中与将它作为 Object 写入流中明显不同。 //由 writeObject 写入的 String 实例最初是作为 String 写入流中的。然后,writeObject() 调用将对该字符串的引用写入流中。 public void writeUTF(String str) throws IOException{} }
二、java.io.Serializable接口
- public interface Serializable
- 类通过实现 java.io.Serializable 接口以启用其序列化功能。
- 未实现此接口的类将无法使其任何状态序列化或反序列化。
- 可序列化类的所有子类型本身都是可序列化的。
- 序列化接口没有方法或字段,仅用于标识可序列化的语义。
- 当遍历一个图形时,可能会遇到不支持 Serializable 接口的对象。
- 在此情况下,将抛出 NotSerializableException,并将标识不可序列化对象的类。
- writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以恢复它
- 序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,
- 该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。
- 如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,
- 则反序列化将会导致 InvalidClassException。
- 可序列化类可以通过声明名为 "serialVersionUID" 的字段
- 该字段必须是静态 (static)、最终 (final) 的 long 型字段,显式声明其自己的 serialVersionUID
- 如:ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
- 如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,
- 不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,
- 原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,
- 根据编译器实现的不同可能千差万别,
- 这样在反序列化过程中可能会导致意外的 InvalidClassException。
- 因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,
- 序列化类必须声明一个明确的 serialVersionUID 值。
- 还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),
- 原因是这种声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没有用处。
- 数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,
- 但是数组类没有匹配 serialVersionUID 值的要求。
- 没有方法的接口叫做标记接口 相当于加个标记
- 静态成员不能被序列化,因为它存放在方法区,那么想让堆中的成员也不被序列化可以加个修饰符:transient
三、ObjectInputStream
- ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
- ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,
- 可以为应用程序提供对对象图形的持久存储。
- ObjectInputStream 用于恢复那些以前序列化的对象。
- 其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。
- 默认情况下,对象的反序列化机制会将每个字段的内容恢复为写入时它所具有的值和类型。
- 反序列化进程将忽略声明为瞬态或静态的字段。
- 对其他对象的引用使得根据需要从流中读取这些对象。
- 使用引用共享机制能够正确地恢复对象的图形。
- 反序列化时始终分配新对象,这样可以避免现有对象被重写。
- 读取对象类似于运行新对象的构造方法。
- 为对象分配内存并将其初始化为零 (NULL)。
- 为不可序列化类调用无参数构造方法,然后从以最接近 java.lang.object 的可序列化类开始和以对象的最特定类结束的流恢复可序列化类的字段。
- 其构造方法与方法均与ObjectOutputStream一一对应
四、示例
import java.io.*; public class ObjectStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { writeObj(); readObj(); } public static void readObj() throws IOException, ClassNotFoundException { FileInputStream fis = new FileInputStream("e:/p.object"); ObjectInputStream ois = new ObjectInputStream(fis); Person p = (Person)ois.readObject(); System.out.println(p); } public static void writeObj() throws IOException { FileOutputStream fos = new FileOutputStream("e:/p.object"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(new Person("zhangsan",20)); oos.close(); System.out.println("已成功保存对象"); } } class Person implements Serializable { String name; int age; transient String sex = "man"; Person(String name,int age) { this.name = name; this.age = age; } public String toString() { return name+":"+age+":"+sex; } } //结果为:zhangsan:20:null如果把transient改为static 结果为:zhangsan:20:man
相关推荐
Java IO系统提供了丰富的类来支持不同类型的输入输出操作,包括但不限于文件读写、网络通信等。本文将通过分析一张清晰明了的Java IO类层次图,详细介绍Java IO体系中的主要类及其关系。 #### 二、Java IO 类层次...
Java中的输入输出流(IO)和非阻塞输入输出流(NIO)是两种重要的数据传输方式,它们在处理程序与外部资源之间的数据交互时起着核心作用。本文将深入探讨这两种技术,以及它们在实际开发中的应用。 一、IO(Input/...
在Java编程语言中,对象输入输出流(Object Input/Output Stream)是用于序列化和反序列化对象的关键组件。这个图书管理系统项目显然依赖于这些功能来存储和恢复系统的状态,比如书籍信息、借阅记录等。以下是关于...
### io包中常用类的作用、重要方法及类之间的继承关系 #### 一、概述 Java的`io`包提供了大量的类来处理输入/输出操作,包括文件读写、网络通信等场景。这些类的设计遵循了良好的面向对象设计原则,通过抽象类和...
"Java 输入输出流及文件读写详解" 本文档对 Java 中的输入输出流和文件读写进行了详细的介绍。从 I/O 类的体系结构开始,讲解了 Java 中的输入输出流的分类,包括字节流和字符流,以及它们之间的区别。然后,着重...
这篇文档主要涵盖了Java输入输出流的基本概念、数据流分类、标准数据流、Java.io包中的数据流和文件类以及文件操作类的方法。 1. 数据流的概念: 流是一种数据处理的概念,分为输入流和输出流。在Java中,流可以...
java.io包中还提供了一些高级的输入输出流类,如BufferedReader、BufferedWriter、DataInputStream、DataOutputStream等,它们提供了缓冲、格式化、日期和时间等高级功能。 Java中的输入输出流是一种非常重要的功能...
2.不属于java.io包中的接口的一项是(C) a)DataInput b) DataOutput c) DataInputStream d) ObjectInput 3. ByteArrayOutputStream将下列哪一项作为输出流 C a) 字符b)字节c)字节数组D)对象 4. 下列流中哪一个...
IO流用来处理设备之间的数据传输。 java对数据的操作是通过流的方式。 java用于操作流的对象都在IO包中。 续51IO流,下载此文件,可先下载之前上传的51IO流
### Java输入输出流基础知识 #### 一、引言 Java作为一种广泛应用的编程语言,其强大的...随着实践的深入,开发者还可以探索更多高级的输入输出流技术,如NIO(New IO)、管道流等,进一步提升程序的性能和灵活性。
Java 输入与输出流是Java编程语言中至关重要的概念,它涉及到数据在程序、文件、网络之间的传输。在Java中,I/O(Input/Output)处理是通过一系列的类和接口来实现的,这些都位于java.io包中。下面将详细阐述Java...
Java的输入输出流是Java程序设计中的重要组成部分,主要用于实现程序与外部设备间的数据交互。在Java中,I/O(Input/Output)流系统是一个庞大的类库,它封装了底层操作系统对数据输入输出的复杂操作,使得开发者...
文件输入输出流是Java.IO包中的关键类,用于处理程序与磁盘文件之间的数据传输。在这个“coreJava文件输入输出流源代码”中,我们可以深入学习输入输出流的原理,以及如何在实际应用中运用这些原理。 1. 输入流...
一、输入输出流 输入输出流是 Java 中最基本的输入输出方式。输入流是从外部设备读取数据的流,而输出流是将数据写入外部设备的流。输入输出流的最基本特点是读写操作按照序列顺序进行。 二、InputStream 和 ...
### Java输入输出流详解 #### 一、Java IO 概述 在计算机程序设计中,输入输出(Input/Output,简称IO)是非常重要的一个概念。它涉及到程序如何与外部世界进行数据交换,最常见的外部设备包括磁盘存储和网络通信等...
在Java编程语言中,文件输入输出流(File I/O Stream)是处理文件数据的基本机制。本文将深入探讨这个主题,包括基本概念、类库、使用示例以及常见问题。 一、基本概念 文件输入流(FileInputStream)和文件输出流...
在Java编程语言中,输入输出流(Input/Output Stream)是进行数据传输的关键概念,用于在不同源和目的地之间建立通信通道。第15章主要探讨了Java中的输入输出流和文件操作,这对于任何Java程序员来说都是至关重要的...
Java数据输入输出流是Java IO库中的重要组成部分,主要用于处理不同数据类型的输入和输出操作,尤其是在文件和网络通信中。本文将深入探讨DataInputStream和DataOutputStream这两个类以及它们所关联的DataInput和...
### Java输入输出流详解 #### 一、Java输入输出流概览 在Java编程中,输入输出(简称IO)操作是极为重要的一个环节,它涉及应用程序与外部设备之间的数据交互,如磁盘读写、网络通信等。Java的IO操作主要通过`java...