1. 本地方法
1.1 什么是本地方法?
- 簡單地講,一個本地方法(Native Method)就是一個Java調用非Java代碼的接口。本地方法的實現由非Java語言實現,比如C/C++。
- 在定義一個本地方法時,并不提供方法體(與定義一個Java接口類似),因為其方法體是由非Java語言在外部實現的。
- 本地方法接口(Native Method Interface, JNI)的作用是融合不同的編程語言為Java所用,它的初衷是融合C/C++程序。
\\ 本地方法定義 示例
public class NativeMethodTest {
public native void nativeMethod1(int x);
public native static long nativeMethod2();
private native synchronized float nativeMethod3(Object o);
native void nativeMethod4(int[] ary) throws Exception;
}
標識符native可以與其它所有的Java標識符連用,但是abstract除外。
3.2 為什么要使用本地方法?
Java使用起來非常方便,然而有些層次的任務用Java實現起來不容易,或者對Java程序的效率不滿意。
- 與Java環境外交互
有時Java應用需要與Java外面的環境交互,這是本地方法存在的主要原因。想象Java需要與一些底層系統,如操作系統或某些硬件交換信息時的情況。本地方法正是這樣一種交流機制:它為我們提供了一個非常簡潔的接口,而且我們無需去了解Java應用之外的繁瑣的細節。
- 與操作系統交互
JVM支持著Java語言本身和運行時庫,它時Java程序賴以生存的平臺,它由一個解釋器(解釋字節碼)和一些連接到本地代碼的庫組成。然而不管怎樣,它畢竟不是一個完整的系統,經常依賴于一些底層系統的支持。這些底層系統常常是強大的操作系統。通過使用本地方法,我們得以實現了jre與底層系統的交互,甚至JVM的一些部分就是用C寫的。還有,如果我們要使用一些Java語言本身沒有提供封裝的操作系統的特性時,我們也需要使用本地方法。
- Sun's Java
Sun的解釋器是用C實現的,這使得它能像一些普通的C一樣與外部交互。jre大部分是用Java實現的,它也通過一些本地方法與外界交互。例如:類
java.lang.Thread
的setPriority()
是用Java實現的,但是它實現調用的是該類里的本地方法setPriority0()
。這個本地方法是用C實現的,并被植入JVM內部,在Windows 95的平臺上,這個本地方法最終將調用Win32setPriority()
API。這是一個本地方法的具體實現由JVM直接提供,更多的是本地方法由外部的動態鏈接庫(external dynamic link library)提供,然后被JVM調用。
現狀
目前該方法使用得越來越少了,除非是與硬件相關的應用,比如通過Java程序驅動打印機或者Java系統管理設備,在企業級應用中已經比較少見。因為現在的異構領域間的通信很發達,比如可以使用Socket通信,也可以使用Web Service等等,不多做介紹。
2.2 本地方法棧
虛擬機棧為虛擬機執行Java方法(也就是字節碼)提供服務,本地方法棧為虛擬機使用到的本地方法服務。
有的虛擬機(如HotSpot)直接將本地方法棧和虛擬機棧合二為一。
當某個線程調用一個本地方法時,它就進入了一個全新的并且不再受虛擬機限制的世界。它和虛擬機擁有同樣的權限。
- 本地方法甚至可以通過本地方法接口來訪問虛擬機內部的運行時數據區。
- 它甚至可以直接使用本地處理器中的寄存器。
- 直接從本地內存的堆中分配任意數量的內存。