This commit is contained in:
Hongkuan Wang 2020-10-09 10:37:18 +08:00 committed by GitHub
parent 7dc616e6d7
commit 0434fa9c49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -199,7 +199,7 @@ class Alien
正如大家所看到的,默认的序列化机制并不难操纵。然而,如果有特殊的需要那又该怎么办呢?例如,也许要考虑特殊的安全问题,而且你不希望对象的某一部分被序列化;或者一个对象被还原以后,某子对象需要重新创建,从而不必将该子对象序列化。
在这些特殊情况下,可通过实现 Externalizable 接口——代替实现 Serializable 接口-来对序列化过程进行控制。这个 Externalizable 接口继承了 Serializable 接口同时增添了两个方法writeExternal0 和 readExternal0。这两个方法会在序列化和反序列化还原的过程中被自动调用,以便执行一些特殊操作。
在这些特殊情况下,可通过实现 Externalizable 接口——代替实现 Serializable 接口-来对序列化过程进行控制。这个 Externalizable 接口继承了 Serializable 接口同时增添了两个方法writeExternal() 和 readExternal()。这两个方法会在序列化和反序列化还原的过程中被自动调用,以便执行一些特殊操作。
下面这个例子展示了 Externalizable 接口方法的简单实现。注意 Blip1 和 Blip2 除了细微的差别之外,几乎完全一致(研究一下代码,看看你能否发现):
@ -366,7 +366,7 @@ Blip3.readExternal
A String 47
```
其中,字段 s 和只在第二个构造器中初始化,而不是在默认的构造器中初始化。这意味着假如不在 readExternal0 中初始化 s 和 is 就会为 null就会为零(因为在创建对象的第一步中将对象的存储空间清理为 0。如果注释掉跟随于"You must do this”后面的两行代码然后运行程序就会发现当对象被还原后s 是 null而 i 是零。
其中,字段 s 和 i 只在第二个构造器中初始化,而不是在默认的构造器中初始化。这意味着假如不在 readExternal() 中初始化 s 和 is 就会为 null而 i 就会为零(因为在创建对象的第一步中将对象的存储空间清理为 0。如果注释掉跟随于"You must do this”后面的两行代码然后运行程序就会发现当对象被还原后s 是 null而 i 是零。
我们如果从一个 Externalizable 对象继承,通常需要调用基类版本的 writeExternal() 和 readExternal() 来为基类组件提供恰当的存储和恢复功能。
@ -552,7 +552,7 @@ writeObject() 方法必须检查 sc判断它是否拥有自己的 writeObject
## 使用持久化
个比较诱人的使用序列化技术的想法是:存储程序的一些状态,以便我们随后可以很容易地将程序恢复到当前状态。但是在我们能够这样做之前,必须回答几个问题。如果我们将两个对象-它们都具有指向第三个对象的引用-进行序列化,会发生什么情况?当我们从它们的序列化状态恢复这两个对象时,第三个对象会只出现一次吗?如果将这两个对象序列化成独立的文件,然后在代码的不同部分对它们进行反序列化还原,又会怎样呢?
个比较诱人的使用序列化技术的想法是:存储程序的一些状态,以便我们随后可以很容易地将程序恢复到当前状态。但是在我们能够这样做之前,必须回答几个问题。如果我们将两个对象-它们都具有指向第三个对象的引用-进行序列化,会发生什么情况?当我们从它们的序列化状态恢复这两个对象时,第三个对象会只出现一次吗?如果将这两个对象序列化成独立的文件,然后在代码的不同部分对它们进行反序列化还原,又会怎样呢?
下面这个例子说明了上述问题: