再来认识一下 Java 序列化 (2)

如果一个变量同时包含 transient 和 static 关键字,并且该值在声明期间被初始化,则它将被序列化。因为在这里 transient 修饰符会被忽略,而 static 修饰符将执行操作。

final 变量将被序列化。

如果一个变量同时包含 final 和 transient 关键字,那么它就会被序列化。因为在这里 transient 修饰符会被忽略,而 final 修饰符将执行操作。

下面用一段代码验证一些。

1、定义一个实例化类

再来认识一下 Java 序列化

2、序列化

再来认识一下 Java 序列化

3、反序列化

再来认识一下 Java 序列化

4、输出结果

再来认识一下 Java 序列化

重点:

One 和 Two 为 null,根据规则 1,使用 tresient 修饰的变量不参与序列化

Three 为 null,根据规则 2, static 变量不参与序列化

Four 之所以为 V4,根据规则 3,仅在声明期间初始化该值,静态变量才会被序列化

Five 为 null,根据规则4,因为它被 static 和 tresient 同时修饰,并且值在生命期间未初始化

Six 之所以为 6,根据规则 4,如果同时 static 和 tresient 同时修饰,并且该值在声明期间已初始化,那就会被序列化

Seven 是 V7,根据规则 5,用 final 修饰的会被序列化

Eight 之所以为 V8,根据规则 6,如果变量同时被 final 和 tresient 修饰,那就会被序列化

serialVersionUID 具体作用是什么?

在序列化中,还有一个特别重要的步骤,需要指定 serialVersionUID 版本号。

如果反序列化使用的 Class 的版本号与序列化时候使用的不一致,则会报异常。

序列化版本号可以随意的指定

如果不指定,JVM 会 自己计算 一个版本号,但随着 Class 的升级,就无法正确反序列化

不指定版本号还有另一个明显隐患,不利于 JVM 间的移植,可能 Class 文件没有更改,但不同 JVM 可能计算的规则不一样,这样也会导致无法反序列化

Java 序列化的缺陷

无法跨平台

现在的系统设计越来越多元化,项目里可能会用多种语言来编写应用程序,比如 Java、C++、Python 同时配合使用。

而 Java 序列化只适用于基于 Java 语言实现的框架。其他语言大部分没有使用 Java 的序列化框架。如果两个基于不同语言编写的应用程序相互通信,那么久无法实现两个应用服务之间的序列化与反序列化。

容易被攻击

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpygdz.html