改善Java程序建議13

建議13:避免為final變量復(fù)雜賦值

為final變量賦值可以通過方法賦值,即直接在聲明時通過方法返回值賦值。

public class Person implements Serializable {
  private static final long serialVerisionUID = 91282334L;
  //通過方法返回值為final變量賦值
  public final String name = initName();
  //初始化方法名
  public String initName(){
    return "混世魔王";
    //  return "德天使";
  }
}

先序列化上面的代碼,然后把initName的返回值改為注釋的代碼。然后在反序列化,name值是什么?

是“混世魔王”,雖然上一條建議說final變量會被重新賦值,其中的“值”指的是簡單對象,簡單對象包括:8個基本數(shù)據(jù)類型,以及數(shù)組,字符串(字符串情況很復(fù)雜,不通過new關(guān)鍵字生成String對象的情況下,final變量的賦值與基本類型相同),但是不能通過方法賦值。

其中的原理是這樣的,保存到磁盤上(或網(wǎng)絡(luò)傳輸)的對象文件包括兩部分:
(1)類描述信息
包括包路徑、繼承關(guān)系、訪問權(quán)限、變量描述、變量訪問權(quán)限、方法簽名、返回值,以及變量的關(guān)聯(lián)類信息。要注意的一點是,它并不是class文件的翻版,它不記錄方法、構(gòu)造函數(shù)、static變量等的具體實現(xiàn)。之所以類描述會被保存,很簡單,是因為能去也能回嘛,這保證反序列化的健壯運行。
(2)非瞬態(tài)(transient關(guān)鍵字)和非靜態(tài)(static關(guān)鍵字)的實例變量值
注意,這里的值如果是一個基本類型,就是一個簡單值保存下來;如果是復(fù)雜對象,連該對象和關(guān)聯(lián)類信息一起保存,并且持續(xù)遞歸下去(關(guān)聯(lián)類也必須實現(xiàn)Serializable接口,否則會出現(xiàn)序列化異常),也就是說遞歸到最后,其實還是基本數(shù)據(jù)類型的保存。
正是因為這兩點原因,一個持久化后的對象文件會比一個class類文件大很多。
總結(jié)一下,反序列化時final變量在以下情況下不會被重新賦值:

  • 通過構(gòu)造函數(shù)為final變量賦值。
  • 通過方法返回值為final變量賦值。
  • final修飾的屬性不是基本類型。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,740評論 18 399
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,456評論 0 16
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,818評論 11 349
  • (一)Java部分 1、列舉出JAVA中6個比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨云閱讀 7,265評論 0 62
  • 上帝賜予我們一雙眼睛,是讓我們善于觀察發(fā)現(xiàn)生活的美。 薯條是大家喜歡的零食之一,最近小朋友喜歡上了吃薯條,孩子奶奶...
    小惠_f2b8閱讀 182評論 0 3

友情鏈接更多精彩內(nèi)容