回答
當SLak回答時,native
關鍵字用於調用本地代碼。
它也被GWT用於實現javascript方法。
它標誌着一種方法,它將用其他語言而不是Java來實現。它與JNI(Java本地接口)一起工作。
過去使用本地方法來編寫性能關鍵部分,但隨着Java變得更快,現在不太常見。當需要本地方法時
您需要從Java調用其他語言編寫的庫。
您需要訪問只能從其他語言(通常爲C)訪問的系統或硬件資源。實際上,許多與真實計算機交互的系統函數(例如磁盤和網絡IO)只能這樣做,因爲它們調用本地代碼。
這是我的理解我在java文件中編寫System.currentTimeMillis()(這是本地的)然後這個工作,JNI將調用庫或一些用C或C++或彙編語言編寫的函數,然後將一些值返回給我的java代碼。例如:這裏currentTimeMillis方法在JNI的幫助下調用一個本地代碼,並且本地代碼與系統資源ex通信:一個坐在主板上的計時器,從而獲得返回值(系統時間)。請糾正我? – MKod 2014-12-25 08:28:07
像'currentTimeMillis'這樣的@MKod方法是JDK的一部分,它們使用'native'註釋,因爲實現在JDK源代碼本身。實現使用匯編語言的可能性很小;它可能會調用JVM正在運行的操作系統的API方法。例如,在Windows上,它可能會在kernel32.dll中調用DLL方法'GetSystemTime'。在另一個操作系統上它會有不同的實現。但是,當您使用'native'作爲您正在編寫的方法(而不是JDK方法)時,您必須使用JNI提供實現。 – Kidburla 2015-10-14 14:35:51
此聲明對Native關鍵字非常重要......「您需要訪問只能從其他語言(通常爲C)可訪問的系統或硬件資源」。 – atiqkhaled 2017-02-26 15:55:25
直從the Java Language Specification:
即
native
在依賴於平臺的代碼實現的,典型地寫在其他編程語言如C,C++的方法, FORTRAN或彙編語言。方法native
的主體僅以分號給出,表示實現被省略,而不是塊。
實現本機代碼的函數被聲明爲本機。
Java本機接口(JNI)是一種編程框架,能夠在Java虛擬機(JVM)打電話,並通過調用,本地應用程序(特定於硬件和操作系統的程序運行Java代碼平臺)和使用其他語言編寫的庫,如C,C++和彙編語言。
天然是在Java中的關鍵字,它用於使未實現結構(方法)等作爲抽象但它是一個依賴於平臺的,例如本機代碼,並從本地棧不是Java堆執行。
NATIVE是非訪問修飾符,它只能應用於METHOD。它指示方法或代碼的PLATFORM-DEPENDENT implimentation。
小例子使事情更清晰:
Main.java:
public class Main {
public native int square(int i);
public static void main(String[] args) {
System.loadLibrary("Main");
System.out.println(new Main().square(2));
}
}
MAIN.C:
#include <jni.h>
#include "Main.h"
JNIEXPORT jint JNICALL Java_Main_square(
JNIEnv *env, jobject obj, jint i) {
return i * i;
}
編譯並運行:
sudo apt-get install build-essential openjdk-7-jdk
export JAVA_HOME='/usr/lib/jvm/java-7-openjdk-amd64'
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main
輸出:
4
測試在Ubuntu 14.04 AMD64。還與Oracle JDK 1.8.0_45合作。
強調了必須在C函數名_1
轉義Java包/文件名如提到:Invoking JNI functions in Android package name containing underscore
解讀:
它允許你:
- 通話編譯的動態加載庫(這裏用C語言編寫),並帶有Java
- 的任意彙編代碼和得到的結果返回到Java的
這可以用於:
- 寫上一個關鍵部分更快的代碼具有更好的CPU安裝說明(不是CPU便攜式)
- 進行直接的系統調用(不OS便攜式)
與便攜性較低的權衡。
也可以爲你從C調用Java,但你必須先在C上創建一個JVM:How to call Java functions from C++?
的Android NDK
的概念是準確的在這方面是相同的,不同之處你必須使用Android樣板進行設置。
官方NDK庫包含 「規範」 的例子,如HELLO-JNI應用:
- https://github.com/googlesamples/android-ndk/blob/4df5a2705e471a0818c6b2dbc26b8e315d89d307/hello-jni/app/src/main/java/com/example/hellojni/HelloJni.java#L39
- https://github.com/googlesamples/android-ndk/blob/4df5a2705e471a0818c6b2dbc26b8e315d89d307/hello-jni/app/src/main/cpp/hello-jni.c#L27
在你unzip
的.apk
與NDK Android上的O,你可以看到對應於lib/arm64-v8a/libnative-lib.so
下的本地代碼的預編譯的.so
。
TODO確認:此外,file /data/app/com.android.appname-*/oat/arm64/base.odex
,說,這是一個共享庫,我認爲這是預編譯.DEX對應於ART的Java文件的AOT,還看到:What are ODEX files in Android?所以,也許在Java實際上也通過native
運行接口?
例中的OpenJDK 8
讓我們找到找到其中Object#clone
在jdk8u60-B27定義。
我們將得出結論,它是通過調用native
來實現的。
首先,我們發現:
find . -name Object.java
這使我們jdk/src/share/classes/java/lang/Object.java#l212:
protected native Object clone() throws CloneNotSupportedException;
現在到了最困難的部分,發現其中克隆之中所有的間接。幫助我的查詢是:
find . -iname object.c
這將找到可能實現對象的本地方法C或C++文件。它使我們jdk/share/native/java/lang/Object.c#l47:
static JNINativeMethod methods[] = {
...
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
這使我們的JVM_Clone
符號:
grep -R JVM_Clone
這使我們hotspot/src/share/vm/prims/jvm.cpp#l580:
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
擴大了一堆宏之後,我們來得出這是定義的結論。
像你這樣的答案是我喜歡並持續使用StackOverflow的原因。如果您可以投票將答案與接受的答案進行合併,或者以某種方式將兩個答案標記爲已接受,那將會非常棒。 – 2015-11-10 05:13:29
@JonnyHenly謝謝!合併會很有趣,但是由於我們已經投票贊成,所以很難派發代表,也許這並不重要。我們可能會看到有一天是:http://meta.stackexchange.com/questions/15805/how-can-we-make-good-answers-to-old-questions-float-to-the-top – 2015-11-10 06:59:07
它是總是很高興看到具有詳細示例代碼的答案。 – 2016-04-10 07:07:12
native
是java中的關鍵字,它表示依賴於平臺。native
方法充當Java(JNI)和其他編程語言之間的接口。
native關鍵字用於聲明在平臺相關代碼(如C或C++)中實現的方法。當一個方法被標記爲本地時,它不能有一個正文,而必須以分號結尾。 Java本地接口(JNI)規範管理實現本地方法的規則和準則,例如Java和本機應用程序之間的數據類型轉換。
下面的示例示出了一類具有聲明爲本地的方法:
public class NativeExample {
public native void fastCopyFile(String sourceFile, String destFile);
}
的NATIVË關鍵字用於聲明其在依賴於平臺的代碼,如C或C++實現的方法。當一個方法被標記爲本地時,它不能有一個正文,而必須以分號結尾。 Java本地接口(JNI)規範管理實現本地方法的規則和準則,例如Java和本機應用程序之間的數據類型轉換。
下面的示例示出了具有一個方法的類聲明爲天然
public class NativeExample {
public native void fastCopyFile(String sourceFile, String destFile);
}
的本地方法缺點:
本地方法存儲與.DLL(動態鏈接庫)在Windows中的文件擴展名。 DLL文件是機器相關的。因此,本地方法是不可移植的。
由於原生方法使用機器碼,因此會導致嚴重的安全問題。
native關鍵字被施加到一個方法,以表明該方法在本地代碼使用JNI(Java本地接口)實現。本地是適用於修改器只適用於方法,我們不能在其他地方應用。在C,C++中實現的方法稱爲本地方法或外部方法。
native關鍵字的主要目標是:
- 爲了提高系統的性能。
- 實現任務級別/內存級別的通信。
- 使用已有的傳統非Java代碼。
- 1. 什麼是Java中的關鍵字?
- 2. 「native」關鍵字在JavaScript中的含義是什麼?
- 3. 什麼是Java的「自我」關鍵字
- 4. 什麼是typeof關鍵字
- 5. 什麼是RCS關鍵字?
- 6. Java鍵碼194,關鍵是什麼?
- 7. C#中的Register關鍵字是什麼?
- 8. JavaScript中的`name`關鍵字是什麼?
- 9. 什麼是PHP中的`finally`關鍵字?
- 10. 什麼是Oracle中的'THE'關鍵字?
- 11. Xcode中的(named)關鍵字是什麼?
- 12. 什麼是Swift中的'const'關鍵字?
- 13. swift中的「as」關鍵字是什麼
- 14. 什麼是PLSQL中的RESULT關鍵字?
- 15. 什麼是Swift中的「open」關鍵字?
- 16. C++中的explicit關鍵字是什麼?
- 17. 在Java中,爲什麼instanceof是關鍵字而不是方法?
- 18. 同步Java塊中volatile關鍵字的重要性是什麼?
- 19. 什麼是Java中C#'var'關鍵字的等價物?
- 20. Java和C++中static關鍵字的含義是什麼?
- 21. 什麼是PHP 5中java「super」關鍵字的等價物?
- 22. java中「This」關鍵字的用法是什麼?
- 23. 什麼是在java中使用「this」關鍵字
- 24. 在這個java方法中超級關鍵字是什麼?
- 25. 未使用的java關鍵字的目的是什麼?
- 26. 什麼是synchronized關鍵字的使用?
- 27. 什麼是新的關鍵字?
- 28. 'final'關鍵字的含義是什麼?
- 29. 「With」關鍵字的功能是什麼
- 30. $ this關鍵字的含義是什麼?
另請參見[Java中的本機實現](http://stackoverflow.com/q/557574/122607),[本機在Java中的使用](http://stackoverflow.com/q/2902618/122607)和[本機關鍵字的作用是什麼?](http://stackoverflow.com/q/3598315/122607)。 – Pops 2011-05-23 18:53:17