1. static
/**
* Created by fun on 2017/2/13.
*/
public class StaticDemo {
private static String prop = null;
static{
prop = "static";
System.out.println("static code block.......");
}
public StaticDemo(){
prop = "constructor";
System.out.println("constructor.......");
}
public static void sayHello(){
System.out.println("sayHello method print the prop="+prop);
}
public void sayHello2(){
prop = "sayHello2";
System.out.println("sayHello2 method print the prop="+prop);
}
}
- 使用StaticDemo的任何方法(靜態(tài)或者非靜態(tài)方法),static代碼塊僅且執(zhí)行一次
- 非靜態(tài)成員方法可以操作靜態(tài)成員變量的值
- 構造方法只在new 關鍵字出現(xiàn),new新的對象的時候調用,使用類名直接調用靜態(tài)方法的時候沒有調用構造方法
- static不能用來修飾普通內部類中的變量,如果內部類本身是static的是可以的
2. final
在java中,可能使用到final關鍵字修飾的有數(shù)據(jù)、方法和類。
2.1 final 修飾數(shù)據(jù)
有final修飾的數(shù)據(jù)是用來告訴編譯器一塊數(shù)據(jù)是恒定不變的,有時數(shù)據(jù)恒定不變是很有用的,比如:
- 一個永不改變的編譯時常量。
- 一個在運行時被初始化的值,但是又不希望它被改變。
編譯時常量必須是基本數(shù)據(jù)類型,并且以關鍵字final修飾,在對這個常量進行定義的時候必須進行賦值,并且以后不能被改變。
對于基本類型,final使數(shù)值恒定不變;而對于對象引用,final使引用恒定不變,也就是說某個引用不能再指向其他對象了,但是當前指向的這個對象自身的數(shù)據(jù)是可以改變的。
如何理解上面的解釋呢,看如下示例:
public void test(final Student student) {
// student = new Student() // 這種寫法就會報錯,因為改變了student的指向,但是student是個final的。
student.setName("123"); // 這種操作是可以的,并且student的name會被成功修改
}
2.2 final修飾方法
使用final修飾方法的作用是把方法鎖定,以防止任何繼承類修改它的含義。在繼承類中,使用了與父類用final修飾的方法同名的方法時,并沒有覆蓋父類的該方法,而是生成了一個新的方法。也就是說final修飾的方法不能被重寫。
2.3 final修飾類
當將某個類定義為final時,就表明了你不打算繼承該類,也不允許別人繼承。
3. transient
使用transient 關鍵字,標記變量不被序列化和反序列化
談到序列化,static 變量也是不會被序列化的
4. volatile
volatile 可以保證變量對所有線程的可見性,但是不能說是完全的線程,例如++ 操作是個非原子操作,就有可能出現(xiàn)問題
volatile只保證了可見性,在不滿足以下情況的時候,需要加鎖(synchronized 或者 java.util.concurrent中的原子類)來保證原子性
- 運算結果并不依賴變量的當前值,后者能夠確保只有單一線程修改變量的值
- 變量不需要同其他的狀態(tài)變量一起參與不變約束
volatile 修飾long / double 在多線程的時候可以把他們的讀寫變成原子的操作(現(xiàn)代的虛擬機已經把64位數(shù)據(jù)讀寫作為原子操作了)
volatile可以防止指令重排序