http://wenjiesu.iteye.com/blog/799332
【java中為什麼會有final變量】:
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變量永遠指向某個對象,是一個常量指針,而不是指向常量的指針。
===========================================================================================
【final關鍵字的具體應用】:
【final+變量】:
在實際應用中,這種形式是非常少見的。
比如logger是可以的,但是貌似并不是非常實用,或許使用者仍然希望通過setter來改變logger變量。
【static+final+變量】:
常量。經常使用。
【final+方法】:
jdk中常用,但是自己并未常用。
【final+類】:
helper類經常使用。
【final用于匿名内部類的參數傳遞】:
在多線程測試時,經常使用。
【final用于方法的參數】:
并不常用。