Java 源代码 随手记录 一 java.io.Serializable

本文深入探讨了Java中类的序列化原理,包括如何通过实现java.io.Serializable接口使类具备序列化能力,序列化接口的基本概念,以及默认计算serialVersionUID的机制。强调了显式声明serialVersionUID的重要性以确保跨不同Java编译器实现的一致性。
这个只是一个Java源代码的部分记录,免得有时候想去看了,还要打开编译器。

Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this
interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassException during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.
### Java `Serializable` 接口的作用 `Serializable` 是个标记接口,用于指示某个类的对象可以通过标准机制进行序列化操作[^1]。当个类实现了 `java.io.Serializable` 接口时,意味着它的实例可以被转换成字节流形式以便于在网络上传输或存储到文件中。 #### 主要作用 - **对象持久化**:允许将对象的状态保存至磁盘或其他外部介质上,并能够在稍后的时刻恢复其状态[^3]。 - **跨进程通信**:支持分布式环境中不同 JVM 之间传递复杂数据结构(如 RMI 或者消息队列中的消息体),前提是这些数据能够被序列化并反序列化回来[^4]。 --- ### 使用场景分析 以下是几个典型的使用案例: 1. **远程过程调用 (RPC)** 当应用程序需要通过网络发送对象作为参数或者返回值时,通常要求这些对象可序列化。例如,在微服务架构下客户端和服务端交互过程中经常涉及此类需求。 2. **缓存系统** 如果希望把某些临时性的计算结果暂存在内存以外的地方,则可能需要用到序列化技术来完成这目标。 3. **数据库存储** 对象可以直接写入二进制格式的数据表字段里再读取出来重建原样副本[^5]. --- ### 如何实现 Serializable 接口? 由于它只是个标志性质的空接口,因此只需要简单声明即可: ```java import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = 1L; // 可选但推荐设置 String name; transient int age; // 不会被序列化的成员变量前加上transient关键字修饰 public Person(String n, int a){ this.name=n; this.age=a; } } ``` 上述代码片段展示了如何创建个基本的支持序列化的类。注意这里还包含了两个重要概念: - `serialVersionUID`: 这是用来验证版本致性的唯标识符。如果不显式指定,默认情况下编译器会基于类的内容生成个哈希值。但是这样可能导致即使只是修改注释也会改变ID从而引发兼容性问题所以最好手动设定固定数值。 - `transient` 关键字标注那些不想参与序列化进程里的属性。 另外还可以重载默认行为来自定义更复杂的逻辑处理方式比如覆盖特殊的方法像 `writeObject()` 和 `readObject()`, 它们会在执行相应动作之前自动调用[^2]: ```java private void writeObject(java.io.ObjectOutputStream out) throws IOException{ out.defaultWriteObject(); } private void readObject(java.io.ObjectInputStream in )throws IOException , ClassNotFoundException{ in .defaultReadObject(); } ``` 以上例子演示了怎样扩展基础功能以满足特定业务的需求。 --- ### 注意事项 尽管方便易用,但在实际开发工作中应谨慎考虑是否真的有必要让某类型具备此特性因为这可能会带来额外负担包括但不限于性能损耗、维护成本上升等问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值