哈哈,樓主很棒
以下都是我復(fù)制的
JNI是Java語(yǔ)言一種特征技術(shù),它允許Java類的某些方法原生實(shí)現(xiàn),同時(shí)讓他們能夠像普通Java方法一樣被調(diào)用和使用。從Java1.1開(kāi)始,JNI標(biāo)準(zhǔn)成為java平臺(tái)的一部分,它允許Java代碼和其他語(yǔ)言寫(xiě)的代碼進(jìn)行交互。JNI一開(kāi)始是為了本地已編譯語(yǔ)言,尤其是C和C++而設(shè)計(jì)的,但是它并不妨礙你使用其他編程語(yǔ)言,只要調(diào)用約定受支持就可以了。使用java與本地已編譯的代碼交互,通常會(huì)喪失平臺(tái)可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的。例如,使用一些舊的庫(kù),與硬件、操作系統(tǒng)進(jìn)行交互,或者為了提高程序的性能。JNI標(biāo)準(zhǔn)至少要保證本地代碼能工作在任何Java?虛擬機(jī)環(huán)境下。
JNI可以這樣與本地程序進(jìn)行交互:
1、你可以使用JNI來(lái)實(shí)現(xiàn)“本地方法”(native methods),并在JAVA程序中調(diào)用它們。
2、JNI支持一個(gè)“調(diào)用接口”(invocation interface),它允許你把一個(gè)JVM嵌入到本地程序中。本地程序可以鏈接一個(gè)實(shí)現(xiàn)了JVM的本地庫(kù),然后使用“調(diào)用接口”執(zhí)行JAVA語(yǔ)言編寫(xiě)的軟件模塊。例如,一個(gè)用C語(yǔ)言寫(xiě)的瀏覽器可以在一個(gè)嵌入式JVM上面執(zhí)行從網(wǎng)上下載下來(lái)的applets。
JNI的副作用
一旦使用JNI,JAVA程序就喪失了JAVA平臺(tái)的兩個(gè)優(yōu)點(diǎn):
1、程序不再跨平臺(tái)。要想跨平臺(tái),必須在不同的系統(tǒng)環(huán)境下重新編譯本地語(yǔ)言部分。
2、程序不再是絕對(duì)安全的,本地代碼的不當(dāng)使用可能導(dǎo)致整個(gè)程序崩潰。一個(gè)通用規(guī)則是,你應(yīng)該讓本地方法集中在少數(shù)幾個(gè)類當(dāng)中。這樣就降低了JAVA和C之間的耦合性。
什么場(chǎng)合下應(yīng)該使用JNI
當(dāng)你開(kāi)始著手準(zhǔn)備一個(gè)使用JNI的項(xiàng)目時(shí),請(qǐng)確認(rèn)是否還有替代方案。像上一節(jié)所提到的,應(yīng)用程序使用JNI會(huì)帶來(lái)一些副作用。下面給出幾個(gè)方案,可以避免使用JNI的時(shí)候,達(dá)到與本地代碼進(jìn)行交互的效果:
1、JAVA程序和本地程序使用TCP/IP或者IPC進(jìn)行交互。
2、當(dāng)用JAVA程序連接本地?cái)?shù)據(jù)庫(kù)時(shí),使用JDBC提供的API。
3、JAVA程序可以使用分布式對(duì)象技術(shù),如JAVA IDL API。
這些方案的共同點(diǎn)是,JAVA和C處于不同的線程,或者不同的機(jī)器上。這樣,當(dāng)本地程序崩潰時(shí),不會(huì)影響到JAVA程序。
下面這些場(chǎng)合中,同一進(jìn)程內(nèi)JNI的使用無(wú)法避免:
1、程序當(dāng)中用到了JAVA API不提供的特殊系統(tǒng)環(huán)境才會(huì)有的特征。而跨進(jìn)程操作又不現(xiàn)實(shí)。
2、你可能想訪問(wèn)一些己有的本地庫(kù),但又不想付出跨進(jìn)程調(diào)用時(shí)的代價(jià),如效率,內(nèi)存,數(shù)據(jù)傳遞方面。
3、JAVA程序當(dāng)中的一部分代碼對(duì)效率要求非常高,如算法計(jì)算,圖形渲染等。
總之,只有當(dāng)你必須在同一進(jìn)程中調(diào)用本地代碼時(shí),再使用JNI。
JNI的設(shè)計(jì)目的
標(biāo)準(zhǔn)的java類庫(kù)可能不支持你的程序所需的特性?;蛟S你已經(jīng)有了一個(gè)用其他語(yǔ)言寫(xiě)成的庫(kù)或程序,而你希望在java程序中使用它。
你可能需要用底層語(yǔ)言實(shí)現(xiàn)一個(gè)小型的時(shí)間敏感代碼,比如匯編,然后在你的java程序中調(diào)用這些功能。