1. 程式人生 > >Java關鍵字之native,strictfp,transient,volatile

Java關鍵字之native,strictfp,transient,volatile

 Java關鍵字(keywords)
  • abstract    default    if            private      this
    boolean     do         implements    protected    throw
    break       double     import        public       throws
    byte        else       instanceof    return       transient
    case        extends    int           short        try
    catch       final      interface     static       void
    char        finally    long          strictfp    
volatile
class       float      native        super        while
const       for        new           switch
continue    goto       package       synchronized

以上是java specifications中定義的keywords,一共48個,其中常見的三個看似是關鍵字的true, false, null,都不是關鍵字,而是作為一個單獨標識型別。
其中,不常用到的關鍵字有:const,goto,native,strictfp,transient,volatile

constgotojava中的保留字。
1. native
native是方法修飾符。Native方法是由另外一種語言(如c/c++,FORTRAN,彙編)實現的本地方法。因為在外部實現了方法,所以在java程式碼中,就不需要聲明瞭,有點類似於藉口方法。Native可以和其他一些修飾符連用,但是abstract方法和Interface方法不能用native來修飾。
Example:
Java程式碼 複製程式碼
  1. publicinterface TestInterface {  
  2.      void doMethod();  
  3. }  
  4. publicclass Test implements TestInterface {  
  5.     publicnativevoid doMethod();  
  6.     privatenativeint doMethodB();  
  7.   publicnativesynchronized String doMethodC();  
  8.   staticnativevoid doMethodD();  
  9. }  
public interface TestInterface {
     void doMethod();
}
public class Test implements TestInterface {
    public native void doMethod();
    private native int doMethodB();
  public native synchronized String doMethodC();
  static native void doMethodD();
}

為什麼需要使用native method?請參考:
http://www.javaeye.com/topic/72543  java Native Method初涉
2. strictfp
修飾類和方法,意思是FP-strict,精確浮點,符合IEEE-754規範的。當一個class或interface用strictfp宣告,內部所 有的float和double表示式都會成為strictfp的。Interface method不能被宣告為strictfp的,class的可以。
Example:
Java程式碼 複製程式碼
  1. strictfpinterface FPTest {  
  2.      void methodA();  
  3. }  
  4. class FPClass implements FPTest {  
  5.     publicvoid methodA() {  
  6.     }  
  7.     publicvoid methodB() {  
  8.   }  
  9.   publicstrictfpvoid methodC() {  
  10.   }  
  11. }  
  12. class FPClassB {  
  13.     strictfpvoid methodA() {  
  14.     }  
  15. }  
strictfp interface FPTest {
     void methodA();
}
class FPClass implements FPTest {
    public void methodA() {
    }
    public void methodB() {
  }
  public strictfp void methodC() {
  }
}
class FPClassB {
    strictfp void methodA() {
    }
}

3.transient
變數修飾符。標記為transient的變數,在物件儲存時,這些變數狀態不會被持久化。當物件序列化的儲存在儲存器上時,不希望有些欄位資料被儲存,為了保證安全性,可以把這些欄位宣告為transient。
4. volatile
volatile修飾變數。在每次被執行緒訪問時,都強迫從共享記憶體中重讀該成員變數的值。而且,當成員變數發生變化時,強迫執行緒將變化值回寫到共享記憶體。這樣在任何時刻,兩個不同的執行緒總是看到某個成員變數的同一個值。
看看Java Language Specification中的例子。
條件:一個執行緒不停的呼叫方法one(),一個執行緒不停的呼叫方法two()。我測試過多次,這種情況好像一直沒有出現。
Java程式碼 複製程式碼
  1. class Test {  
  2.     staticint i = 0, j = 0;  
  3.     staticvoid one() { i++; j++; }  
  4.     staticvoid two() {  
  5.         System.out.println("i=" + i + " j=" + j);  
  6.     }  
  7. }  
class Test {
	static int i = 0, j = 0;
	static void one() { i++; j++; }
	static void two() {
		System.out.println("i=" + i + " j=" + j);
	}
}

結果偶爾會出現j大於i的情況,因為方法沒有同步,所以會出現i和j可能不是一次更新。一種防止這種情況發生的辦法就是宣告兩個方法為synchronized 的。
Java程式碼 複製程式碼
  1. class Test {  
  2.     staticint i = 0, j = 0;  
  3.     staticsynchronizedvoid one() { i++; j++; }  
  4.     staticsynchronizedvoid two() {  
  5.         System.out.println("i=" + i + " j=" + j);  
  6.     }  
  7. }  
class Test {
	static int i = 0, j = 0;
	static synchronized void one() { i++; j++; }
	static synchronized void two() {
		System.out.println("i=" + i + " j=" + j);
	}
}

這樣可以防止兩個方法同時被執行,還可以保證j和i被同時更新,這樣一來i和j的值一直是一樣的。
另外一種途徑就是把i和j宣告為volatile
Java程式碼 複製程式碼
  1. class Test {  
  2.     staticvolatileint i = 0, j = 0;  
  3.     staticvoid one() { i++; j++; }  
  4.     staticvoid two() {  
  5.         System.out.println("i=" + i + " j=" + j);  
  6.     }