在ssh框架中,使用零配置,实体类必须要实现 java.io.Serializable接口,否则报错.
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。
要允许不可序列化类的子类型序列化,可以假定该子类型负责保存和恢复超类型的公用 (public)、受保护的 (protected) 和(如果可访问)包 (package) 字段的状态。仅在子类型扩展的类有一个可访问的无参数构造方法来初始化该类的状态时,才可以假定子类型有此职责。如果不是这种情况,则声明一个类为可序列 化类是错误的。该错误将在运行时检测到。
在反序列化过程中,将使用该类的公用或受保护的无参数构造方法初始化不可序列化类的字段。可序列化的子类必须能够访问无参数构造方法。可序列化子类的字段将从该流中恢复。
当遍历一个图形时,可能会遇到不支持 Serializable 接口的对象。在此情况下,将抛出 NotSerializableException,并将标识不可序列化对象的类。
在序列化和反序列化过程中需要特殊处理的类必须使用下列准确签名来实现特殊方法:
private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException;
writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以恢复它。通过调用 out.defaultWriteObject 可以调用保存 Object 的字段的默认机制。该方法本身不需要涉及属于其超类或子类的状态。通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream,状态可以被保存。
readObject 方法负责从流中读取并恢复类字段。它可以调用 in.defaultReadObject 来调用默认机制,以恢复对象的非静态和非瞬态字段。defaultReadObject 方法使用流中的信息来分配流中通过当前对象中相应指定字段保存的对象的字段。这用于处理类演化后需要添加新字段的情形。该方法本身不需要涉及属于其超类或 子类的状态。通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream,状态可以被保存。
在序列化流不列出给定类作为将被反序列化对象的超类的情况下,readObjectNoData 方法负责初始化特定类的对象状态。这在接收方使用的反序列化实例类的版本不同于发送方,并且接收者版本扩展的类不是发送者版本扩展的类时发生。在序列化流 已经被篡改时也将发生;因此,不管源流是“敌意的”还是不完整的,readObjectNoData 方法都可以用来正确地初始化反序列化的对象。
将对象写入流时需要指定要使用的替代对象的可序列化类,应使用准确的签名来实现此特殊方法:
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
此 writeReplace 方法将由序列化调用,前提是如果此方法存在,而且它可以通过被序列化对象的类中定义的一个方法访问。因此,该方法可以拥有私有 (private)、受保护的 (protected) 和包私有 (package-private) 访问。子类对此方法的访问遵循 java 访问规则。
在从流中读取类的一个实例时需要指定替代的类应使用的准确签名来实现此特殊方法。
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
此 readResolve 方法遵循与 writeReplace 相同的调用规则和访问规则。
序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该 对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException
。可序列化类可以通过声明名为 "serialVersionUID"
的字段(该字段必须是静态 (static)、最终 (final) 的 long
型字段)显式声明其自己的 serialVersionUID:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException
。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private
修饰符显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没有用处。数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,但是数组类没有匹配 serialVersionUID 值的要求。
相关推荐
### Java.io.Serializable 序列化问题详解 #### 一、序列化的概念与作用 在 Java 编程语言中,序列化是一种将对象的状态(即成员变量的值)转换为可以存储或传输的形式的过程。通常,这种形式是字节流,但也可以是...
### Java.io.InvalidClassException Local Class Incompatible 解决方案 在Java序列化过程中,经常会遇到`java.io.InvalidClassException`异常,特别是在序列化类时如果类的版本与反序列化环境中的类版本不一致的...
java.lang.Throwable (implements java.io.Serializable) java.lang.Exception java.lang.RuntimeException com.opensymphony.xwork2.XWorkException (implements com.opensymphony.xwork2.util.location.Locatable...
24. `java.io.Serializable`:Serializable接口用于对象序列化,允许对象的状态被保存和恢复。 25. `java.util.LinkedList`:LinkedList是双向链表实现的List,适合频繁插入和删除操作。 26. `java.text....
这个过程涉及到`java.io.Serializable`接口,任何需要被序列化的类都必须实现这个接口。以下是一个简单的序列化和反序列化的例子: ```java import java.io.*; class Student implements Serializable { String ...
Java.io包支持对象的序列化和反序列化,通过实现`Serializable`接口,可以将对象转换为字节流,便于存储或网络传输。 7. **文件操作**: `File` 类是文件和目录操作的主要接口,可以创建、删除、重命名文件和目录...
import java.io.Serializable; @SuppressWarnings("serial") //一个类要想实现序列化则必须实现Serializable接口 class Person implements Serializable { private String name; private int age; public ...
NotSerializableException 是 Java 中的一个异常,它发生在尝试序列化一个不implement Serializable 接口的对象时。今天,我们将讨论 Java 中序列化 NotSerializableException 问题的解决办法。 问题描述 --------...
java.util.HashMap,V> (implements java.lang.Cloneable, java.util.Map,V>, java.io.Serializable) java.util.LinkedHashMap,V> (implements java.util.Map,V>) org.springframework.core.annotation....
本文实例讲述了Android开发实现的IntentUtil跳转多功能工具类。...import java.io.Serializable; import android.app.Activity; import android.content.Context; import android.content.Intent; import andr
`java.io.Serializable` 接口是实现序列化的基础。Android 中,虽然不常用 Java Beans 的序列化,但仍然可以使用这个机制来保存对象状态。 6. **Introspection**: `java.beans.Introspector` 类提供了一种动态分析 ...
Java的`java.io.ObjectOutputStream`和`java.io.ObjectInputStream`可以配合`java.io.Serializable`接口实现对象的序列化和反序列化,而`javax.xml.bind.JAXBContext`和`javax.xml.bind.Marshaller`等类可以实现XML...
- **对象的序列化**:为了保存对象到文件,对象必须实现`java.io.Serializable`接口。创建一个对象输出流(`ObjectOutputStream`),通过它将对象写入文件。 - **对象的反序列化**:使用`ObjectInputStream`从文件...
例如,`java.util.Comparator`接口用于比较对象,而`java.io.Serializable`接口则表示类可以被序列化。 4. **枚举(Enum)**:Java允许定义枚举类型,这是一种特殊的类,可以有预定义的实例。比如`java.util....
import java.io.Serializable; public class Box implements Serializable { private static final long serialVersionUID = 1L; private int width; private int height; private String name; public ...
import java.io.Serializable; public class Box implements Serializable { private static final long serialVersionUID = 1L; private int width; private int height; private String name; public void ...
import java.io.Serializable; import java.util.HashMap; import java.util.Map; import com.google.gson.JsonObject; import com.google.gson.JsonArray; import net.sf.json.JSONObject; import org.apache....
### Java JDK IO包类详解 #### 概述 Java平台提供的`io`包为开发者提供了访问文件系统、对象序列化等功能的基本输入输出能力。它主要包括字节流、字符流及对象流(字节流的包装类)。此外,还提供了一些基本的文件...
import java.io.Serializable; import java.io.FileOutputStream; import java.io.ObjectOutputStream; class TestSerial implements Serializable { public byte version = 100; public byte count = 0; } ...
要实现Java对象的序列化,首先需要让对象所属的类实现`java.io.Serializable`接口。这个接口是一个标记接口,不包含任何方法,它的作用是告诉Java虚拟机该类的对象是可以被序列化的。例如: ```java import java.io...