•序列化 ID 的問(wèn)題
•靜態(tài)變量序列化
•父類(lèi)的序列化與 Transient 關(guān)鍵字
•對(duì)敏感字段加密
•序列化存儲(chǔ)規(guī)則
列表的每一部分講述了一個(gè)單獨(dú)的情境,讀者可以分別查看。
--------------------------------------------------------------------------------
回頁(yè)首
序列化 ID 問(wèn)題
情境:兩個(gè)客戶端 A 和 B 試圖通過(guò)網(wǎng)絡(luò)傳遞對(duì)象數(shù)據(jù),A 端將對(duì)象 C 序列化為二進(jìn)制數(shù)據(jù)再傳給 B,B 反序列化得到 C。
問(wèn)題:C 對(duì)象的全類(lèi)路徑假設(shè)為 com.inout.Test,在 A 和 B 端都有這么一個(gè)類(lèi)文件,功能代碼完全一致。也都實(shí)現(xiàn)了 Serializable 接口,但是反序列化時(shí)總是提示不成功。
解決:虛擬機(jī)是否允許反序列化,不僅取決于類(lèi)路徑和功能代碼是否一致,一個(gè)非常重要的一點(diǎn)是兩個(gè)類(lèi)的序列化 ID 是否一致(就是 private static final long serialVersionUID = 1L)。清單 1 中,雖然兩個(gè)類(lèi)的功能代碼完全一致,但是序列化 ID 不同,他們無(wú)法相互序列化和反序列化。
清單 1. 相同功能代碼不同序列化 ID 的類(lèi)對(duì)比
package com.inout;
import java.io.Serializable;
public class A implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
package com.inout;
import java.io.Serializable;
public class A implements Serializable {
private static final long serialVersionUID = 2L;
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
復(fù)制代碼
序列化 ID 在 Eclipse 下提供了兩種生成策略,一個(gè)是固定的 1L,一個(gè)是隨機(jī)生成一個(gè)不重復(fù)的 long 類(lèi)型數(shù)據(jù)(實(shí)際上是使用 JDK 工具生成),在這里有一個(gè)建議,如果沒(méi)有特殊需求,就是用默認(rèn)的 1L 就可以,這樣可以確保代碼一致時(shí)反序列化成功。那么隨機(jī)生成的序列化 ID 有什么作用呢,有些時(shí)候,通過(guò)改變序列化 ID 可以用來(lái)限制某些用戶的使用。