我們前面在介紹 JDK 源碼 Object.class 類的時候,講過 getClass() 方法、hashCode()方法、clone() 方法,其中方法簽名如下:
public final native Class< ? > getClass();
public native int hashCode();
protected native Object clone() throws CloneNotSupportedException;
你敢說你沒用過這些方法?如果你用過,那你就是一定用過不是Java語言編寫的方法。
答案就是【native】關(guān)鍵詞,用此關(guān)鍵詞修飾的方法,多數(shù)情況就不是用Java實現(xiàn)的。
那么為什么要用 native 來修飾方法,這樣做有什么用?
1、JNI:Java Native Interface
在介紹 native 之前,我們先了解什么是 JNI。
一般情況下,我們完全可以使用 Java 語言編寫程序,但某些情況下,Java 可能會不滿足應(yīng)用程序的需求,或者是不能更好的滿足需求,比如:
①、標(biāo)準(zhǔn)的 Java 類庫不支持應(yīng)用程序平臺所需的平臺相關(guān)功能。
②、我們已經(jīng)用另一種語言編寫了一個類庫,如何用Java代碼調(diào)用?
③、某些運行次數(shù)特別多的方法代碼,為了加快性能,我們需要用更接近硬件的語言(比如匯編)編寫。
上面這三種需求,其實說到底就是如何用 Java 代碼調(diào)用不同語言編寫的代碼。那么 JNI 應(yīng)運而生了。
從Java 1.1開始,Java Native Interface (JNI)標(biāo)準(zhǔn)就成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設(shè)計 的,但是它并不妨礙你使用其他語言,只要調(diào)用約定受支持就可以了。使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統(tǒng)進行交互,或者為了提高程序的性能。JNI標(biāo)準(zhǔn)至少保證本地代碼能工作在任何Java 虛擬機實現(xiàn)下。
通過 JNI,我們就可以通過 Java 程序(代碼)調(diào)用到操作系統(tǒng)相關(guān)的技術(shù)實現(xiàn)的庫函數(shù),從而與其他技術(shù)和系統(tǒng)交互,使用其他技術(shù)實現(xiàn)的系統(tǒng)的功能;同時其他技術(shù)和系統(tǒng)也可以通過 JNI 提供的相應(yīng)原生接口開調(diào)用 Java 應(yīng)用系統(tǒng)內(nèi)部實現(xiàn)的功能。
在windows系統(tǒng)上,一般可執(zhí)行的應(yīng)用程序都是基于 native 的PE結(jié)構(gòu),windows上的 JVM 也是基于native結(jié)構(gòu)實現(xiàn)的。Java應(yīng)用體系都是構(gòu)建于 JVM 之上。
可能有人會問,Java不是跨平臺的嗎?如果用 JNI,那么程序不就將失去跨平臺的優(yōu)點?確實是這樣的。
JNI 的缺點:
①、程序不再跨平臺。要想跨平臺,必須在不同的系統(tǒng)環(huán)境下重新編譯本地語言部分。
②、程序不再是絕對安全的,本地代碼的不當(dāng)使用可能導(dǎo)致整個程序崩潰。一個通用規(guī)則是,你應(yīng)該讓本地方法集中在少數(shù)幾個類當(dāng)中。這樣就降低了JAVA和C之間的耦合性。
目前來講使用 JNI 的缺點相對于優(yōu)點還是可以接受的,可能后面隨著 Java 的技術(shù)發(fā)展,我們不在需要 JNI,但是目前 JDK 還是一直提供對 JNI 標(biāo)準(zhǔn)的支持。
3、用C語言編寫程序本地方法
上面講解了什么是 JNI,那么我們接下來就寫個例子,如何用 Java 代碼調(diào)用本地的 C 程序。
官方文檔如下:https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
步驟如下:
①、編寫帶有 native 聲明的方法的java類,生成.java文件;(注意這里出現(xiàn)了 native 聲明的方法關(guān)鍵字)
②、使用 javac 命令編譯所編寫的java類,生成.class文件;
③、使用 javah -jni java類名 生成擴展名為 h 的頭文件,也即生成.h文件;
④、使用C/C++(或者其他編程語言)實現(xiàn)本地方法,創(chuàng)建.h文件的實現(xiàn),也就是創(chuàng)建.cpp文件實現(xiàn).h文件中的方法;
⑤、將C/C++編寫的文件生成動態(tài)連接庫,生成dll文件;
下面我們通過一個 HelloWorld 程序的調(diào)用來完成這幾個步驟。
注意:下面所有操作都是在所有操作都是在目錄:D:JNI 下進行的。
一、編寫帶有 native 聲明的方法的java類
public class HelloJNI {
//native 關(guān)鍵字告訴 JVM 調(diào)用的是該方法在外部定義
private native void helloJNI();
static{
System.loadLibrary("helloJNI");//載入本地庫
}
public static void main(String[] args) {
HelloJNI jni = new HelloJNI();
jni.helloJNI();
}
}
用 native 聲明的方法表示告知 JVM 調(diào)用,該方法在外部定義,也就是我們會用 C 語言去實現(xiàn)。
System.loadLibrary("helloJNI");加載動態(tài)庫,參數(shù) helloJNI 是動態(tài)庫的名字。我們可以這樣理解:程序中的方法 helloJNI() 在程序中沒有實現(xiàn),但是我們下面要調(diào)用這個方法,怎么辦呢?我們就需要對這個方法進行初始化,所以用 static 代碼塊進行初始化。
這時候如果我們直接運行該程序,會報“A Java Exception has occurred”錯誤:
二、使用 javac 命令編譯所編寫的java類,生成.class文件
執(zhí)行上述命令后,生成 HelloJNI.class 文件:
三、使用 javah -jni java類名 生成擴展名為 h 的頭文件
執(zhí)行上述命令后,在 D:/JNI 目錄下多出了個 HelloJNI.h 文件:
四、使用C語言實現(xiàn)本地方法 如果不想安裝visual studio 的,我們需要在 windows平臺安裝 gcc。
安裝教程如下:http://blog.csdn.net/altland/article/details/63252757
注意安裝版本的選擇,根據(jù)系統(tǒng)是32位還是64位來選擇。64位點擊下載。
安裝完成之后注意配置環(huán)境變量,在 cmd 中輸入 g++ -v,如果出現(xiàn)如下信息,則安裝配置完成:
接著輸入如下命令:
gcc -m64 -Wl,--add-stdcall-alias -I"C:Program FilesJavajdk1.8.0_152include" -I"C:Program FilesJavajdk1.8.0_152includeincludewin32" -shared -o helloJNI.dll helloJNI.c
-m64表示生成dll庫是64位的。后面的路徑表示本機安裝的JDK路徑。生成之后多了一個helloJNI.dll 文件
最后運行 HelloJNI:輸出 Hello JNI! 大功告成。
4、JNI調(diào)用C的流程圖
圖片引用自:https://www.cnblogs.com/Qian123/p/5702574.html
5、native關(guān)鍵字
通過上面介紹了那么多JNI的知識,終于到介紹本篇文章的主角——native 關(guān)鍵字了。相信大家看完上面的介紹,應(yīng)該也是知道什么是 native 了吧。
native 用來修飾方法,用 native 聲明的方法表示告知 JVM 調(diào)用,該方法在外部定義,我們可以用任何語言去實現(xiàn)它。簡單地講,一個native Method就是一個 Java 調(diào)用非 Java 代碼的接口。
native 語法:
①、修飾方法的位置必須在返回類型之前,和其余的方法控制符前后關(guān)系不受限制。
②、不能用 abstract 修飾,也沒有方法體,也沒有左右大括號。
③、返回值可以是任意類型
我們在日常編程中看到native修飾的方法,只需要知道這個方法的作用是什么,至于別的就不用管了,操作系統(tǒng)會給我們實現(xiàn)。
6、小結(jié)
好了,這就是Java中對 native 關(guān)鍵詞的介紹。
-
JAVA
+關(guān)注
關(guān)注
20文章
2988瀏覽量
109292 -
程序
+關(guān)注
關(guān)注
117文章
3826瀏覽量
82874 -
代碼
+關(guān)注
關(guān)注
30文章
4899瀏覽量
70597 -
應(yīng)用程序
+關(guān)注
關(guān)注
38文章
3333瀏覽量
58982
發(fā)布評論請先 登錄
如何通過注解來優(yōu)化我們的Java代碼
【視頻】應(yīng)用開發(fā)第2期:JS+FA調(diào)用Java
如何用java映射創(chuàng)建java對象和調(diào)用java對象呢
如何用java映射創(chuàng)建java對象和調(diào)用java對象的方法
如何用Word調(diào)用Protel For DOS繪制的圖形
Java學(xué)習(xí)路線教程之Java新手必須學(xué)習(xí)那21個技術(shù)點詳細資料說明
HarmonyOS如何自動生成JS FA調(diào)用Java PA的模板代碼
在Java方法中調(diào)用Lua function
java上位機開發(fā)(c庫調(diào)用)

評論