[轉] 再論 java 中的 final 變量

【java中爲何會有final變量】:java

final這個關鍵字的含義是「這是沒法改變的」或者「終態的」;
那麼爲何要阻止改變呢?
java語言的發明者可能因爲兩個目的而阻止改變:
1).效率問題:
    jdk中的某些類的某些方法,是不容許被用戶覆蓋的,設計者可能認爲,所用方法已是最好的方法,
    用戶私自覆蓋,或是因爲疏忽而覆蓋,就會影響JVM或是系統的系能;
2). 設計所需:
    衆所周知,有些狀況必須使用final關鍵字,好比方法中的匿名內部類的參數傳遞;

【final關鍵字的使用方法】:多線程

【修飾變量】:
    final成員變量表示常量,只能被賦值一次,賦值後值再也不改變。
【修飾方法】:
    final方法不能被子類方法覆蓋,但能夠被繼承。
【修飾類】:
    final類不能被繼承,沒有子類,final類中全部方法都是final的。

【final的內存分配方式】:函數

【修飾變量】:
    一般狀況下,final變量有3個地方能夠賦值:直接賦值,構造函數中,或是初始化塊中。
    【初始化】:
        因爲在java的語法中,聲明和初始化是聯繫在一塊兒的,
        也就是說:若是你不顯示的初始化一個變量,系統會自動用一個默認值來對其進行初始化。(如int就是0)
        對於final變量,在聲明時,若是你沒有賦值,系統默認這是一個空白域,在構造函數進行初始化,
        若是是靜態的,則能夠在初始化塊。
    【內存】:
         常量(final變量)和非final變量的處理方式是不同的。
         每個類型在用到一個常量時,都會複製一份到本身的常量池中。
         常量也像類變量(static)同樣保存在方法區,只不過他保存在常量池。
         (多是,類變量被全部實例共享,而常量池是每一個實例獨有的。)
【修飾方法】:
    保存在方法區,而且能夠被函數代碼直接替換,而不用等到執行時再決定具體是那個函數。
【修飾類】:
    保存在方法區。

【java中變量的初始化順序】:測試

變量的初始化次序優於任何方法,甚至在構造方法的前面。對於static變量也是同樣,
 若是變量是原始類型,那麼它獲得一個標準的原始類型的初始值,
 若是是一個對象的引用,除非你建立了一個新的對象給這個引用,不然就是null。
 static變量在須要的時候纔會初始化,而且在這個類的構造函數和全部其餘普通變量以前調用,static以後就再也不進行初始化了,
 static變量在類初始化時(注意不是實例),就必須分配內存空間,
 static變量單獨劃分一塊存儲空間。

 java類首次裝入時,會對靜態成員變量或方法進行一次初始化,
 先初始化父類的靜態代碼-->初始化子類的靜態代碼-->
 (建立使歷史,若是不建立實例,則後面的不執行)初始化父類的非靜態代碼-->初始化父類的構造
     -->初始化子類的非靜態代碼-->初始化子類的構造

 類只有在使用new調用建立的時候纔會被java類裝載器裝入。

【final方法爲什麼會高效】:優化

final方法會在編譯的過程當中利用內嵌機制進行inline優化。
inline優化是指:在編譯的時候直接調用函數代碼替換,而不是在運行時調用函數。
inline須要在編譯的時候就知道最後要用哪一個函數,    
顯然,非final是不行的。
非final方法可能在子類中被重寫,因爲可能出現多態的狀況,編譯器在編譯階段
並不能肯定未來調用方法的對象的真正類型,也就沒法肯定到底調用哪一個方法。

【什麼是多態】:線程

按字面的意思是「多種狀態」。在面嚮對象語言中,接口的多種不一樣的實現方式即爲多態。
簡單的說,就是一句話:容許將子類類型的指針賦值給父類類型的指針。

【非final方法爲何會出現多態】:設計

顯然,若是派生出一個子類,覆蓋非final方法,就會出現2個這樣的方法可供調用,這就是多態。

【final變量的變與不變】:指針

有人說final變量在賦值後就不可變,
那麼這個不變到底指的是什麼呢?
這個不變指的是引用,是地址,而所引用的對象的內容仍然是可變的。
就是說,這個final變量永遠指向某個對象,是一個常量指針,而不是指向常量的指針。

===========================================================================================code

【final關鍵字的具體應用】:對象

【final+變量】:
    在實際應用中,這種形式是很是少見的。
    好比logger是能夠的,可是貌似並非很是實用,或許用戶仍然但願經過setter來改變logger變量。
【static+final+變量】:
    常量。常用。
【final+方法】:
    JDK中經常使用,可是本身並未經常使用。
【final+類】:
    helper類常用。
【final用於匿名內部類的參數傳遞】:
    在多線程測試時,常用。
【final用於方法的參數】:
    並不經常使用。
相關文章
相關標籤/搜索