JNI 即 Java Native Interface 是 native 編程接口,它容許在Java虛擬機(VM)內運行Java代碼與其餘編程語言(主要是C和C++)編寫的應用程序和庫進行交互操做。html
JNI最重要的好處是它對底層Java VM的實現沒有任何限制。所以,Java VM供應商能夠添加對JNI的支持,而不會影響VM的其餘部分。程序員能夠編寫一個native應用程序或庫的版本,並指望它能夠與支持JNI的全部Java VM一塊兒使用。java
本文主要將從如下幾點講述JNI相關的內容,用於咱們瞭解JNI:android
概述、背景、目標、實現方式。程序員
雖然您能夠徹底使用Java編寫應用程序,但有些狀況下Java自己並不能知足您的應用程序的需求。當應用程序沒法徹底用Java編寫時,程序員使用JNI編寫Java Native 方法來處理這些狀況。算法
如下示例說明什麼時候須要使用Java Native方法:編程
經過JNI編程,您可使用Native方法:數組
來自不一樣供應商的VM提供了不一樣的Native方法接口。這些不一樣的接口迫使程序員在給定平臺上生成,維護和分發多個版本的本機方法庫。oracle
咱們簡要介紹一些本機方法接口,例如:編程語言
JDK 1.0 附帶了Native方法接口。不幸的是,這個接口不適合其餘Java VM採用有兩個主要緣由。 ide
首先,本機代碼訪問Java對象中的字段做爲C結構的成員。可是,Java語言規範沒有定義對象在內存中的佈局方式。若是Java VM在內存中以不一樣方式佈局對象,則程序員必須從新編譯本機方法庫。
其次,JDK 1.0的本機方法接口依賴於保守的垃圾收集器。unhand
例如,不受限制地使用宏使得必須保守地掃描本機堆棧。
Netscape提出了Java運行時接口(JRI),它是Java虛擬機中提供的服務的通用接口。JRI的設計考慮了可移植性 - 它對底層Java VM中的實現細節作了不多的假設。JRI解決了普遍的問題,包括本機方法,調試,反射,嵌入(調用)等。
Microsoft Java VM支持兩種本機方法接口。在低級別,它提供了有效的原始本機接口(RNI)。RNI提供了與JDK本機方法接口的高度源級向後兼容性,儘管它有一個主要區別。本機代碼必須使用RNI函數與垃圾收集器明確交互,而不是依賴於保守的垃圾收集。
在更高級別,Microsoft的Java / COM接口爲Java VM提供了與語言無關的標準二進制接口。Java代碼能夠像使用Java對象同樣使用COM對象。Java類也能夠做爲COM類公開給系統的其他部分。
咱們相信,統一且通過深思熟慮的標準接口爲每一個人提供如下好處:
實現標準本機方法接口的最佳方法是讓全部各方都參與Java VM。所以,咱們在Java許可證持有者之間組織了一系列關於統一本機方法接口設計的討論。從討論中能夠清楚地看出,標準本機方法接口必須知足如下要求:
咱們但願採用現有方式之一做爲標準,主要是爲了給在不一樣VM中學習多個接口的程序員帶來最小的負擔。可是使人失望的是,目前沒有現有的解決方案來實現咱們這樣的想法。
Netscape的JRI是最接近咱們想要的的便攜式Natvie方法接口,並被用做咱們設計的起點。熟悉JRI的讀者會注意到API命名約定,方法和字段ID的使用,本地和全局引用的使用等方面的類似之處。儘管咱們盡最大努力,但JNI與JRI不是二進制兼容的,儘管VM能夠同時支持JRI和JNI。
微軟的RNI是對JDK 1.0的改進,由於它解決了使用非保守垃圾收集器的本機方法的問題。可是,RNI不適合做爲獨立於VM的本機方法接口。與JDK同樣,RNI本機方法將Java對象做爲C結構訪問,但也致使兩個問題:
做爲二進制標準,COM確保跨不一樣VM的徹底二進制兼容性。調用COM方法只須要間接調用,這幾乎不會產生任何開銷。此外,COM對象在解決版本問題方面比動態連接庫有了很大的改進。
可是,使用COM做爲標準Java本機方法接口受到如下幾個因素的阻礙:
雖然Java對象不做爲COM對象公開給本機代碼,但JNI接口自己與COM二進制兼容。JNI使用與COM相同的跳轉表結構和調用約定。這意味着,只要跨平臺支持COM,JNI就能夠成爲Java VM的COM接口。
JNI不被認爲是給定Java VM支持的惟一本機方法接口。標準接口使程序員受益,他們但願將本機代碼庫加載到不一樣的Java VM中。在某些狀況下,程序員可能必須使用較低級別的VM特定接口來實現最高效率。在其餘狀況下,程序員可能使用更高級別的界面來構建軟件組件。實際上,隨着Java環境和組件軟件技術的日趨成熟,本機方法將逐漸失去意義。
首先本文是譯文,原文地址爲:https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/intro.html。
同時也是本人整理的JNI教程的第一篇,可能部份內容語法有點不通順,可是看完了也能基本瞭解JNI是什麼,產生的背景,以及JNI被實現的方式。
下面附一下學習JNI時推薦的參考資料: