"关于Java序列化的详细解析" Java序列化是Java平台提供的一种持久化机制,它允许将对象的状态转换为字节流,以便可以存储或在网络上传输。这个过程对于实现数据持久化、跨网络通信(如RMI和EJB)以及对象在分布式环境中的传输非常关键。当一个Java对象需要被序列化时,该对象必须实现`java.io.Serializable`接口,这是Java序列化的基础。 1. 实现序列化: - 接口实现:为了使一个类的对象能够被序列化,该类必须直接或间接地实现`Serializable`接口。这个接口是一个标记接口,没有定义任何方法,它的存在只是为了标识一个类是可序列化的。 - 成员变量处理:不是类的所有成员变量都会被序列化。`static`和`transient`修饰的成员变量不会被序列化。`static`变量属于类,而不是单个对象,因此没有必要序列化;而`transient`变量则表示其状态不需要持久化,所以会被忽略。 2. 序列化操作: - 写入对象:使用`FileOutputStream`创建一个输出流,然后通过`ObjectOutputStream`的构造函数将其包装起来。接着,调用`ObjectOutputStream`的`writeObject()`方法,将对象写入到输出流中。例如: ```java import java.io.*; public class Cat implements Serializable { private String name; // 构造器、getter和setter方法略 public static void main(String[] args) { Cat cat = new Cat(); try { FileOutputStream fos = new FileOutputStream("cat.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(cat); oos.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` - 读取对象:反序列化是通过`ObjectInputStream`实现的。首先创建一个`FileInputStream`,然后用它来创建`ObjectInputStream`。接着,调用`readObject()`方法从输入流中读取先前序列化的对象。例如: ```java import java.io.*; public class Main { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("cat.ser"); ObjectInputStream ois = new ObjectInputStream(fis); Cat cat = (Cat) ois.readObject(); ois.close(); System.out.println("Deserialized cat's name: " + cat.getName()); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } } ``` 序列化和反序列化过程中需要注意的是,如果序列化的类在之后进行了修改,比如添加了新的成员变量,那么在反序列化时可能会遇到版本不兼容的问题。为了解决这个问题,Java提供了`serialVersionUID`字段,用于标识序列化版本。如果类中没有显式声明`serialVersionUID`,编译器会自动生成一个,但推荐开发者显式声明,以确保在版本控制中能正确处理序列化对象。 Java序列化是Java开发中不可或缺的一部分,它使得对象的状态能够被保存和恢复,这对于数据持久化、网络通信以及分布式系统中的对象交互具有重要意义。理解并熟练掌握序列化机制可以帮助开发者更好地处理这些问题。
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
2、串行化的特点:
(1)如果某个类能够被串行化,其子类也可以被串行化。如果该类有父类,则分两种情况来考虑,如果该父类已经实现了可串行化接口。则其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现可串行化接口,则该类的父类所有的字段属性将不会串行化。
(2)声明为static和transient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据;
(3)相关的类和接口:在java.io包中提供的涉及对象的串行化的类与接口有ObjectOutput接口、ObjectOutputStream类、ObjectInput接口、ObjectInputStream类。
(1)ObjectOutput接口:它继承DataOutput接口并且支持对象的串行化,其内的writeObject()方法实现存储一个对象。ObjectInput接口:它继承DataInput接口并且支持对象的串行化,其内的readObject()方法实现读取一个对象。
(2)ObjectOutputStream类:它继承OutputStream类并且实现ObjectOutput接口。利用该类来实现将对象存储(调用ObjectOutput接口中的writeObject()方法)。ObjectInputStream类:它继承InputStream类并且实现ObjectInput接口。利用该类来实现读取一个对象(调用ObjectInput接口中的readObject()方法)。
对于父类的处理,如果父类没有实现串行化接口,则其必须有默认的构造函数(即没有参数的构造函数)。否则编译的时候就会报错。在反串行化的时候,默认构造函数会被调用。但是若把父类标记为可以串行化,则在反串行化的时候,其默认构造函数不会被调用。这是为什么呢?这是因为Java 对串行化的对象进行反串行化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成。
import java.io.*;
public class Cat implements Serializable {
private String name;
public Cat () {
this.name = "new cat";
}
public String getName() {
下载后可阅读完整内容,剩余2页未读,立即下载
- 粉丝: 0
- 资源: 1
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 李兴华Java基础教程:从入门到精通
- U盘与硬盘启动安装教程:从菜鸟到专家
- C++面试宝典:动态内存管理与继承解析
- C++ STL源码深度解析:专家级剖析与关键技术
- C/C++调用DOS命令实战指南
- 神经网络补偿的多传感器航迹融合技术
- GIS中的大地坐标系与椭球体解析
- 海思Hi3515 H.264编解码处理器用户手册
- Oracle基础练习题与解答
- 谷歌地球3D建筑筛选新流程详解
- CFO与CIO携手:数据管理与企业增值的战略
- Eclipse IDE基础教程:从入门到精通
- Shell脚本专家宝典:全面学习与资源指南
- Tomcat安装指南:附带JDK配置步骤
- NA3003A电子水准仪数据格式解析与转换研究
- 自动化专业英语词汇精华:必备术语集锦