一、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包中,提供了ObjectInputStream和ObjectOutputStream将数据流功能扩展至可...
IO流用来处理设备之间的数据传输。 java对数据的操作是通过流的方式。 java用于操作流的对象都在IO包中。 续51IO流,下载此文件,可先下载之前上传的51IO流
IO流用来处理设备之间的数据传输。 java对数据的操作是通过流的方式。 java用于操作流的对象都在IO包中。 由于笔记作为两章,这里是第一张,想要了解更多的IO流,请下载第二章52IO流
Java 流相关的类都封装在 java.io 包中,而且每个数据流都是一个对象。所有输入流类都是 InputStream 抽象类(字节输入流)以及 Reader 抽象类(字符输入流)的子类。其中 InputStream 类是字节输入流的抽象类,是...
1.掌握文件类(File类)的使用 2.IO输入/输出流的概念3.IO的分类4.掌握IO包中的流的基本应用5.了解字符编码问题6.掌握对象序列化(串行化)
IO(Input Output)流 IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中 流按操作数据分为两种:字节流与字符流 。 流按流向分为:输入流,输出流。
根据数据流向不同分为:输入流和输出流 字符流和字节流 字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别: 读写...
专业的课程讲解 所有的程序都离不开信息的输入和输出。例如,从键盘读取数据、在网络上交换数据、打印报表、读写文件信息等,都要涉及数据输入输出的处理。...在Java中,处理数据流的类主要被放在java.io包中 。
2.不属于java.io包中的接口的一项是(C) a)DataInput b) DataOutput c) DataInputStream d) ObjectInput 3. ByteArrayOutputStream将下列哪一项作为输出流 C a) 字符b)字节c)字节数组D)对象 4. 下列流中哪一个...
Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。 Java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等
按照流的流向分,可以分为输入流和输出流; 按照操作单元划分,可以划分为字节流和字符流; 按照流的角色划分为节点流和处理流。 按照操作方式分类: 按照操作对象分类: IO 流基础对象: InputStream/Reader: 所有...
12.以下哪个是java.io包中的一个兼有输入输出功能的类。 A、Object B、Serializable C、RandomAccessFile D、java.io中不存在这样的类 13.下面关于线程优先级的说法中,错误的是: A、Java中的线程的优先级有...
11.4字符流的输入输出 11.4.1认识字符流 11.4.2如何读写文件 11.4.3如何进行键盘输入 11.5和IO操作相关的其他类 11.5.1用RandomAccessFile类进行文件读写 11.5.2使用Properties类 11.6小结 第12章多线程开发...
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 17、...
2.1.6 BufferedOutputStream(缓冲输出流) 2.1.7 PrintStream(打印流) 2.2字符流 2.2.1 Reader类 2.2.2 Writer类 2.2.3 FileReader类 2.2.4 FileWriter类 2.2.5 CharArrayReader类 2.2.6 CharArrayWriter类 2.2.7 ...
掌握串行化概念,学会使用FileInputStream,FileOutputStream,ObjectInputStream,ObjectOutputStream等类输入输出对象。 明白通过捕获异常判定输入文件流的结束。 [*]知道使用RandomAccessFile...
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 14、Overload...
java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java 编程语言注释设施提供库支持。 java.lang.instrument 提供...
java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java 编程语言注释设施提供库支持。 java.lang.instrument 提供...