打開java.lang.Object類,我們能發現很多方法上都帶有native這個修飾符。




為什么有個native呢?它是干什么用的?
一、認識native
熟悉JVM體系結構的小伙伴應該會記得,在JVM的體系結構中有一個Java Native Interface模塊,稱為Java本地庫接口,它的作用是融合不同的編程語言為Java所用。Java是一個跨平台的語言,既然是跨了平台,所付出的代價就是犧牲一些對底層的控制,而Java要實現對底層的控制,就需要借助一些其他語言的幫助,這個就是native的作用。
二、什么是native method
簡單的來說,一個Native method就是一個java調用非java代碼的接口:該方法的實現由非java語言實現,比如C。這個特征非Java特有,比如在C++中,就可以用extern "C"告知C++編譯器去調用一個C的函數。
Java中的本地方法棧正是提供了這樣一種功能,它與java虛擬機棧所發揮的作用是非常相似的,其區別不過是虛擬機棧為虛擬機執行 Java 方法(也就是字節碼)服務,而本地方法棧則是為虛擬機使用到的 Native 方法服務。
Navtive 方法是 Java 通過 JNI(Java本地庫接口) 直接調用本地 C/C++ 庫,可以認為是 Native 方法相當於 C/C++ 暴露給 Java 的一個接口,Java 通過調用這個接口從而調用到 C/C++ 方法。當線程調用 Java 方法時,虛擬機會創建一個棧幀並壓入 Java 虛擬機棧。然而當它調用的是 native 方法時,虛擬機會保持 Java 虛擬機棧不變,也不會向 Java 虛擬機棧中壓入新的棧幀,虛擬機只是簡單地動態連接並直接調用指定的 native 方法。

"A native method is a java method whose implementation is provided by non-java code."
在定義一個native method時,並不提供實現體(有些像定義一個java interface),因為其實現體是由非java語言在外面實現的。下面給了一個示例:
package java.lang;
public class Object { ...... public final native Class<?> getClass(); public native int hashCode(); protected native Object clone() throws CloneNotSupportedException; public final native void notify(); public final native void notifyAll(); public final native void wait(long timeout) throws InterruptedException; ...... }
native可以與所有其他的java標識符連用,abstract除外。這是合理的,因為native暗示這些方法室友實現體的,只不過它們不是用java實現的,但abstract卻顯然的指明這些方法無實現體。
native修飾的方法並不會給調用它的類造成任何影響,它與其他method一樣可以返回任何java類型。我們可以將它看做是一個正常的java方法來使用。
三、為什么要使用native method
java在完成某些層次的任務實現起來很容易,因為要兼顧到跨平台,所以很多對底層的操作就不能有太強的耦合。有時java需要與java外面的環境交互,比如底層的操作系統或者某些硬件,這也是本地方法存在的主要原因。通過使用本地方法,我們只需要調用它暴露給我們的接口,而不需要了解java應用之外的繁瑣的細節。
四、JVM怎么使native method跑起來
我們知道,當一個類第一次被使用到的時候,這個類的字節碼會被加載到內存,並且只會加載一次。在這個被夾在的字節碼入口維持着一個該類所有方法描述符的list,這些方法描述符包含這樣一些信息:方法代碼存於何處,它有哪些參數,方法的描述符(public之類)等等。
如果一個方法描述符內有native,那么這個方法將成為Java Native Interface中的一部分,這個描述符塊將有一個指向該方法的實現的指針。這些實現在一些DLL文件內,但是它們會被操作系統加載到java程序的地址空間,這個空間稱為Java Native Method Libraries。當一個帶有本地方法的類被加載時,其相關的DLL並未被加載,因此指向方法實現的指針並不會被設置。當本地方法被調用之前,這些DLL才會被加載,這是通過調用java.system.loadLibrary()實現的。
使用本地方法是有開銷的,它喪失了java的很多好處。如果別無選擇,我們可以選擇使用本地方法。