天天看點

關于内部類為什麼可以有靜态常量,不能有靜态變量的原因?

大部分都是拷貝的别人的!

java類加載順序,首先加載類,執行static變量初始化,接下來執行對象的建立,如果我們要執行代碼中的變量int a 初始化,那麼必須先執行加載外部類,再加載内部類,最後初始化靜态變量 a ,問題就出在加載内部類上面,我們可以把内部類看成外部類的非靜态成員,它的初始化必須在外部類對象建立後以後進行,要加載内部類必須在執行個體化外部類之後完成,java虛拟機要求所有的靜态變量必須在對象建立之前完成,這樣便産生了沖突。而java常量放在記憶體中常量池,它的機制與變量是不同的,編譯時,加載常量是不需要加載類的,是以就沒有上面那種沖突。

預備知識:

● 生命周期(Lifecycle):

靜态方法(Static Method)與靜态成員變量一樣,屬于類本身,在類裝載的時候被裝載到記憶體(Memory),不自動進行銷毀,會一直存在于記憶體中,直到JVM關閉。

非靜态方法(Non-Static Method)又叫執行個體化方法,屬于執行個體對象,執行個體化後才會配置設定記憶體,必須通過類的執行個體來引用。不會常駐記憶體,當執行個體對象被JVM 回收之後,也跟着消失。 

● 在記憶體中存儲位置

靜态方法和靜态變量建立後始終使用同一塊記憶體,是連續的。

非靜态方法會存在于記憶體的多個地方,是離散的。

● 效率

 靜态方法的使用效率比非靜态方法的效率高。

● 線程安全

靜态方法是共享代碼段,靜态變量是共享資料段。既然是“共享”就有并發(Concurrence)的問題。

非靜态方法是針對确定的一個對象的,是以不會存線上程安全的問題。

● 使用範圍

靜态方法:⒈ 有靜态屬性的類,一般會定義靜态方法。⒉ 沒有屬性的類,一般會定義靜态方法。⒊ 如果一個方法與他所在類的執行個體對象無關,那麼它就應該是靜态的。靜态方法可以被繼承但是不能被覆寫。

●  總計

如果靜态方法在系統中定義太多,會占用大量的資源,最後造成記憶體溢出,是以靜态方法不能濫用。如果從線程安全、性能、相容性上來看,選用執行個體化方法為宜。

static 方法 (靜态方法)

方法在該方法所屬類型第一次被使用的時候加載、在該類型所在應用程式域解除安裝的時候解除安裝、也就是說 static 方法隻加載一次、除非整個Domain 被解除安裝了。

執行個體方法(非靜态方法)

方法是在第一次該方法第一次調用的時候會加載、然後被緩存起來。但是中間如果有GC 的話, 就會被收集,那下次再調用該方法時,又得重新加載該方法。也就是說,執行個體方法有可能加載多次。

總的來說,static 方法隻用加載一次,但一直會占用記憶體。多了些資源消耗;而執行個體方法需要加載多次,但不會一直占用記憶體。少些資源消耗。一般來說, 在程式裡面,一些使用頻率高的方法就用static 方法、使用頻率低的則用執行個體方法