序列化java.io.Serializable

本文深入探讨了Java对象序列化和外部化机制,包括它们的区别、优势和劣势,以及如何在实际应用中选择合适的持久化方式。

ava.io.Serializable引发的问题——什么是序列化?在什么情况下将类序列化?
 
 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。
是对象永久化的一种机制。

   确切的说应该是对象的序列化,一般程序在运行时,产生对象,这些对象随着程序的停止运行而消失,但如果我们想把某些对象(因为是对象,所以有各自不同的特性)保存下来,在程序终止运行后,这些对象仍然存在,可以在程序再次运行时读取这些对象的值,或者在其他程序中利用这些保存下来的对象。这种情况下就要用到对象的序列化。

   只有序列化的对象才可以存储在存储设备上。为了对象的序列化而需要继承的接口也只是一个象征性的接口而已,也就是说继承这个接口说明这个对象可以被序列化了,没有其他的目的。之所以需要对象序列化,是因为有时候对象需要在网络上传输,传输的时候需要这种序列化处理,从服务器硬盘上把序列化的对象取出,然后通过网络传到客户端,再由客户端把序列化的对象读入内存,执行相应的处理。

   对象序列化是java的一个特征,通过该特征可以将对象写作一组字节码,当在其他位置读到这些字节码时,可以依此创建一个新的对象,而且新对象的状态与原对象完全相同。为了实现对象序列化,要求必须能够访问类的私有变量,从而保证对象状态能够正确的得以保存和恢复。相应的,对象序列化API能够在对象重建时,将这些值还原给私有的数据成员。这是对java语言访问权限的挑战。通常用在服务器客户端的对象交换上面,另外就是在本机的存储。

   对象序列化的最主要的用处就是在传递,和保存对象(object)的时候,保证对象的完整性和可传递性。譬如通过网络传输,或者把一个对象保存成一个文件的时候,要实现序列化接口 。
*
Quote:


比较java.io.Externalizable和java.io.Serializable 
[URL]http://www.zdnet.com.cn/developer/code/story/0,3800066897,39304080,00.htm[/URL]

即使你没有用过对象序列化(serialization),你可能也知道它。但你是否知道 Java 还支持另外一种形式的对象持久化,外部化(externalization)?

下面是序列化和外部化在代码级的关联方式:

public interface Serializable {}

public interface Externalizable extends Serializable {
void readExternal(ObjectInput in);
void writeExternal(ObjectOutput out);
}

序列化和外部化的主要区别

外部化和序列化是实现同一目标的两种不同方法。下面让我们分析一下序列化和外部化之间的主要区别。

通过Serializable接口对对象序列化的支持是内建于核心 API 的,但是java.io.Externalizable的所有实现者必须提供读取和写出的实现。Java 已经具有了对序列化的内建支持,也就是说只要制作自己的类java.io.Serializable,Java 就会试图存储和重组你的对象。如果使用外部化,你就可以选择完全由自己完成读取和写出的工作,Java 对外部化所提供的唯一支持是接口:

voidreadExternal(ObjectInput in)
void writeExternal(ObjectOutput out)

现在如何实现readExternal() 和writeExternal() 就完全看你自己了。

序列化会自动存储必要的信息,用以反序列化被存储的实例,而外部化则只保存被存储的类的标识。当你通过java.io.Serializable接口序列化一个对象时,有关类的信息,比如它的属性和这些属性的类型,都与实例数据一起被存储起来。在选择走Externalizable这条路时,Java 只存储有关每个被存储类型的非常少的信息。

每个接口的优点和缺点

Serializable接口

· 优点:内建支持

· 优点:易于实现

· 缺点:占用空间过大

· 缺点:由于额外的开销导致速度变比较慢

Externalizable接口

· 优点:开销较少(程序员决定存储什么)

· 优点:可能的速度提升

· 缺点:虚拟机不提供任何帮助,也就是说所有的工作都落到了开发人员的肩上。

在两者之间如何选择要根据应用程序的需求来定。Serializable通常是最简单的解决方案,但是它可能会导致出现不可接受的性能问题或空间问题;在出现这些问题的情况下,Externalizable可能是一条可行之路。

要记住一点,如果一个类是可外部化的(Externalizable),那么Externalizable方法将被用于序列化类的实例,即使这个类型提供了Serializable方法:

private void writeObject()
private void readObject() 

### 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(); } ``` 以上例子演示了怎样扩展基础功能以满足特定业务的需求。 --- ### 注意事项 尽管方便易用,但在实际开发工作中应谨慎考虑是否真的有必要让某类型具备此特性因为这可能会带来额外负担包括但不限于性能损耗、维护成本上升等问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值