java序列化的接口为什么是空的?

Java序列化是JDK1.1时引入的一组开创性的特性,用于将Java对象转换为字节数组,便于存储或传输。此后,仍然可以将字节数组转换回Java对象原有的状态。

序列化的思想是“冻结”对象状态,然后写到磁盘或者在网络中传输;反序列化的思想是“解冻”对象状态,重新获得可用的 Java 对象。

再来看看序列化 Serializbale 接口的定义:

public interface Serializable {                            
                                                                                 
}                                                                             

Serializable 接口之所以定义为空,是因为它只起到了一个标识的作用,告诉程序实现了它的对象是可以被序列化的,但真正序列化和反序列化的操作并不需要它来完成。

java.io.ObjectOutputStream是实现序列化的关键类,它可以将一个对象转换成二进制流,然后可以通过ObjectInputStream将二进制流还原成对象。

ObjectOutputStream在序列化过程中会依次调用:
writeObject() → writeObject() → writeOrdinaryObject() → writeSerialData() → defaultWriteFields()

ObjectInputStream的反序列化过程:
readObject() →readObject() → readOrdinaryObject() →readSerialData() → defaultReadFields()

static 和 transient 修饰的字段是不会被序列化的。

首先,在 Wanger 类中增加两个字段。
在这里插入图片描述
其次,在测试类中打印序列化前和反序列化后的对象,并在序列化后和反序列化前改变 static 字段的值。具体代码如下:在这里插入图片描述
从结果的对比当中,我们可以发现:

1)序列化前,pre 的值为“沉默”,序列化后,pre 的值修改为“不沉默”,反序列化后,pre 的值为“不沉默”,而不是序列化前的状态“沉默”。

为什么呢?因为序列化保存的是对象的状态,而 static 修饰的字段属于类的状态,因此可以证明序列化并不保存 static 修饰的字段。

2)序列化前,meizi 的值为“王三”,反序列化后,meizi 的值为 null,而不是序列化前的状态“王三”。

为什么呢?transient 的中文字义为“临时的”(论英语的重要性),它可以阻止字段被序列化到文件中,在被反序列化后,transient 字段的值被设为初始值,比如 int 型的初始值为 0,对象型的初始值为 null。

很多人觉得自己写得 Java 代码中,新建的 pojo 对象要实现序列化是为了要保存到硬盘上,但是,实现序列化和保存到硬盘上没有必然的关系。
在这里插入图片描述
假设左边的是你的电脑,也就是客户端,右边的是服务器。之前你的客户端和服务器可能都在同一个电脑上,都是 Windows 下,那么右边的服务器也可以放到 Linux 中,这就涉及到左右两个不同的服务器了。中间用一条竖线分隔一下。

客户端可以调用服务器,所以肯定要传递参数。假设你传递的是字符串,没有问题,所有的机器都可以识别正常的字符串。

那么现在假设你传递的参数是一个 Java 对象,比如叫 cat。服务器并没有那么智能,它并不会知道你传递的是一个 Java 对象,而不是其他类型的数据,它识别不了 Java 对象。

Java 对象本质上是 class 字节码,服务器并不能根据这个字节码识别出该 Java 对象。所以,要提供一个公共的格式,不仅 Windows 能识别,你的服务器也能识别的公共的格式。

我们将 Java 对象转换成公共的格式叫做序列化,将公共的格式转换成对象叫做反序列化。保存到磁盘只是序列化的一种表现形式。

序列化其实很好理解,假如你现在做一个项目,项目是分工合作的,并且你喝其他小组成员不在同一个城市,那么你要如何把你写的那些类给其他小组成员呢?这个时候就要用到序列化了,简单的说:序列化就是将内存中的类或者对象(你写的类都是存储在内存中的)变成可以存储到存储媒介中的流,你将类序列化成流之后可以通过互联网传输给别人,你也可以反序列化将别人的序列化流转换成内存中的对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
为什么要实现序列化Java中的序列化是将对象转换为字节序列的过程,可以将序列化后的字节序列保存到本地文件或在网络上传输,最终将其反序列化为原始对象。实现序列化的主要目的是为了在不同的系统、不同的平台之间传输对象,或者将对象持久化保存到本地文件中。例如,在分布式应用程序中,可以通过序列化将对象从一个节点传输到另一个节点,或者将对象保存到数据库中。 如何实现序列化? 在Java中,实现序列化的方式是实现Serializable接口。Serializable接口是一个接口,没有任何方法,其作用是为了标识一个类可以被序列化。如果一个类实现了Serializable接口,那么该类的对象就可以被序列化,即可以被转换为字节序列并进行传输或保存。 需要注意的是,如果一个类中包含了其他对象的引用,那么被引用的对象也必须实现Serializable接口,否则序列化会失败。另外,在序列化的过程中,可能会出现版本不兼容的问题,即当序列化的对象的类发生变化时,反序列化可能会失败。为了解决这个问题,可以在类中添加一个serialVersionUID属性,表示序列化版本的唯一标识,当版本不兼容时,就可以根据serialVersionUID进行版本控制。 在Java中,实现序列化和反序列化的具体代码非常简单,只需要使用ObjectOutputStream和ObjectInputStream类的writeObject和readObject方法即可完成。例如: ```java //将对象序列化到文件中 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.obj")); oos.writeObject(obj); oos.close(); //从文件中读取对象并反序列化 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.obj")); Object obj = ois.readObject(); ois.close(); ``` 需要注意的是,序列化和反序列化过程中可能会出现异常,因此需要进行异常处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Brrby

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值