1. 程式人生 > >面向物件的陷阱——native方法的陷阱

面向物件的陷阱——native方法的陷阱

4、native方法的陷阱

       在Java方法定義中有一類特殊的方法:native方法。對於native方法而言,Java程式不會為該方法提供實現體。
public class NativeTest {
	public native void info();
}
       使用 native修飾的方法就像一個“抽象方法”,只有方法簽名,沒有方法體。從這個意義上來說,native關鍵字和abstract關鍵字有點類似。不過,native方法通常需要藉助C語言來完成,即需要使用C語言為Java方法提供實現。其實現步驟如下。
  1. 用javah編譯第一步生成的class檔案,將產生一個.h檔案。
  2. 寫一個.cpp檔案實現native方法, 其中需要包含第1步產生的.h檔案(.h檔案中又包含了JDK帶的jni.h檔案)。
  3. 將第2步的.cpp檔案編譯成動態連結庫檔案。
  4. 在Java中用system的loadLibrary()方法或Runtime的loadLibrary()方法載入第3步產生的動態連結庫檔案,就可以在Java程式中呼叫這個native方法。
       這裡需要注意的是,在第3步編譯.cpp檔案時,將會使得該程式依賴於當前的編譯平臺。也就是說,native方法做不到跨平臺,它在不同的平臺上可能表現出不同的行為。
public class SleepTest {
	public static void main(String[] args) throws Exception{
		long start = System.currentTimeMillis();
		Thread.sleep(2);
		System.out.println(System.currentTimeMillis() - start);
	}
}
       嘗試編譯、執行上面程式,如果使用Windows XP系統的,大部分都會輸出0,極少數機會輸出16,;如果使用win7系統的,大部分會輸出16.這個執行結果非常的奇怪,當檢視JDK關於Thread.sleep()方法的介紹,發現有如下的解釋:讓當前執行的執行緒sleep(暫停)指定的毫秒數,具體暫停多少毫秒取決於系統計時器的精度。也就是說,Thread的sleep()方法其實是一個 native方法。
       上面程式給出的教訓是,千萬不要過度相信JDK提供的方法。雖然Java語言本身是跨平臺的,但Java的native方法還是要依賴於具體的平臺,尤其是JDK所提供的方法,更是包含了大量的native方法。使用這些方法時,要注意它們在不同平臺上可能出現的差異。