java中 static,final,transient,volatile關鍵字的作用
阿新 • • 發佈:2019-01-03
static 和final
static 靜態修飾關鍵字,可以修飾 變數,程式塊,類的方法;
當你定義一個static的變數的時候jvm會將將其分配在記憶體堆上,所有程式對它的引用都會指向這一個地址而不會重新分配記憶體;
修飾一個程式塊的時候(也就是直接將程式碼寫在static{...}中)時候,虛擬機器就會優先載入靜態塊中程式碼,這主要用於系統初始化;
當修飾一個類方法時候你就可以直接通過類來呼叫而不需要新建物件。
final 只能賦值一次;修飾變數、方法及類,
當你定義一個final變數時,jvm會將其分配到常量池中,程式不可改變其值;當你定義一個方法時,改方法在子類中將不能被重寫;當你修飾一個類時,該類不能被繼承。
static和final使用範圍:類、方法、變數。
2.區別和聯絡:
2.1.static 含義:靜態的,被 static 修飾的方法和屬性只屬於類不屬於類的任何物件。
2.2.static 用法:
2.2.1.static 可以修飾【內部類】、方法和成員變數。
2.2.2.static【不可以修飾外部類】、【不可以修飾區域性變數】(因為 static 本身就是定義為類級別的,所以區域性級別的變數是不可以用 static 修飾的)。
2.3 final 含義:【只能賦值一次】的。
2.2.final 用法:
2.2.1.final 修飾屬性,表示屬性【只能賦值一次】,(1)基本型別:值不能被修改;(2)引用型別:引用不可以被修改該。
2.2.2.final 修飾方法,表示方法不可以重寫,但是可以被子類訪問(如果方法不是 private 型別話)。
2.2.2.final 修飾類,表示類不可以被繼承。
3.聯合使用 static final
3.1.適用範圍:
3.1.2.兩者範圍的交集,所以只能修飾:成員變數、方法、內部類。
3.2.含義:也是二者交集:
3.2.1.方法:屬於類的方法且不可以被重寫。
3.2.2.成員變數:屬於類的變數且只能賦值一次。
3.2.3.內部類:屬於外部類,且不能被繼承
transient
型別修飾符,只能用來修飾字段,如果用transient宣告一個例項變數,當物件儲存時,它的值不需要維持。換句話來說就是,用transient關鍵字標記的成員變數不參與序列化過程。
volatile
volatile也是變數修飾符,只能用來修飾變數。volatile修飾的成員變數在每次被執行緒訪問時,都強迫從共享記憶體中重讀該成員變數的值。而且,當成員變數發生變化時,強迫執行緒將變化值回寫到共享記憶體。這樣在任何時刻,兩個不同的執行緒總是看到某個成員變數的同一個值。
在此解釋一下Java的記憶體機制:
Java使用一個主記憶體來儲存變數當前值,而每個執行緒則有其獨立的工作記憶體。執行緒訪問變數的時候會將變數的值拷貝到自己的工作記憶體中,這樣,當執行緒對自己工作記憶體中的變數進行操作之後,就造成了工作記憶體中的變數拷貝的值與主記憶體中的變數值不同。
Java語言規範中指出:為了獲得最佳速度,允許執行緒儲存共享成員變數的私有拷貝,而且只當執行緒進入或者離開同步程式碼塊時才與共享成員變數的原始值對比。
這樣當多個執行緒同時與某個物件互動時,就必須要注意到要讓執行緒及時的得到共享成員變數的變化。
而volatile關鍵字就是提示VM:對於這個成員變數不能儲存它的私有拷貝,而應直接與共享成員變數互動。
使用建議:在兩個或者更多的執行緒訪問的成員變數上使用volatile。當要訪問的變數已在synchronized程式碼塊中,或者為常量時,不必使用。
由於使用volatile遮蔽掉了VM中必要的程式碼優化,所以在效率上比較低,因此一定在必要時才使用此關鍵字。