十一空民、 養(yǎng)成良好習慣终惑,顯示聲明UID
JVM通過SerialVersionUID(也叫作流標識符)來判斷一個類的版本葫男。
SerialVersionUID的作用:
JVM在反序列化時,會比較數(shù)據(jù)流中的SerialVersionUID與類的SerialVersionUID是否相同恐疲。
如果相同亏镰,則認為類沒有發(fā)生變化扯旷,可以把數(shù)據(jù)流load為實例對象;
如果不相同索抓,JVM拋出異常InvalidClassException钧忽。
顯示聲明SerialVersionUID可以避免對象不一致,但盡量不要以這種方式向JVM“撒謊”逼肯。
十二耸黑、避免用序列化類在構造函數(shù)中為不變量賦值
反序列化時構造函數(shù)不會執(zhí)行。
反序列化的執(zhí)行過程如下:
JVM從數(shù)據(jù)流中獲取一個Object對象汉矿,然后根據(jù)數(shù)據(jù)流中的類文件描述信息(在序列化時崎坊,保存到磁盤的對象文件中
包含了類描述信息备禀,注意是類描述信息洲拇,不是類)查看奈揍,發(fā)現(xiàn)是final變量,需要重新計算赋续,于是引用Person類中的
name值男翰,而此時JVM又發(fā)現(xiàn)name居然沒有賦值,不能引用纽乱,于是它很“聰明”的不再初始化蛾绎,保持原值狀態(tài)。
在序列化類中鸦列,不使用構造函數(shù)為final變量賦值租冠。
十三、避免為final變量復雜賦值
final變量賦值方式:
1. 通過構造函數(shù)賦值
2. 通過方法賦值薯嗤,即直接在聲明中通過方法返回值賦值
反序列化時final變量在以下情況下不會被重新賦值:
* 通過構造函數(shù)為final變量賦值
* 通過方法返回值為final變量賦值
* final修飾的屬性不是基本類型
十四顽爹、 使用序列化類的私有方法巧妙解決部分屬性持久化問題
十五、break萬萬不可忘
記住在case語句后面隨手寫上break骆姐,養(yǎng)成良好的習慣镜粤。
十六、易變業(yè)務用腳本語言編寫
十七玻褪、慎用動態(tài)編譯
在動態(tài)編譯時需要注意以下幾點:
- 在框架中謹慎使用
- 不要在要求高性能的項目中使用
- 動態(tài)編譯要考慮安全問題
- 記錄動態(tài)編譯過程
十八肉渴、避免InstanceOf非預期結果
十九、斷言絕對不是雞肋
在java中斷言使用的是Assert關鍵字带射,其基本的用法如下:
assert <布爾表達式>
assert <布爾表達式> : <錯誤信息>
在以下兩種情況下不可以使用:
- 在對外公開的方法中
- 在執(zhí)行邏輯代碼的情況下
那么在什么情況下可以使用assert呢同规?一句話:按照正常執(zhí)行邏輯不可能到達代碼區(qū)域可以設置assert。具體分為你三種情況:
- 在私有方法中放置assert作為輸入?yún)?shù)的校驗
- 流程控制中不可能到達的區(qū)域
- 建立程序探針
二十窟社、不要只替換一個類
發(fā)布應用系統(tǒng)時禁止使用類文件替換方式捻浦,整體war包發(fā)布才是萬全之策。