What is the native keyword in Java for?
在玩这个谜题(它是一个Java关键词琐事游戏)时,我遇到了EDCOX1的0个关键字。
Java中的原生关键字是什么?
它标志着一种方法,它将用其他语言实现,而不是在Java中实现。它与JNI(Java本机接口)一起工作。
过去使用本地方法编写性能关键部分,但随着Java速度的提高,这一点不再常见。当
您需要从Java中调用其他语言编写的库。
您需要访问只能从其他语言(通常是C语言)访问的系统或硬件资源。实际上,许多与真实计算机交互的系统功能(例如磁盘和网络IO)只能这样做,因为它们调用本机代码。
也见Java本地接口规范
最简单的例子让事情更清楚:
Main.java:
1 2 3 4 5 6 7 |
主要内容:
1 2 3 4 5 6 7 | #include <jni.h> #include"Main.h" JNIEXPORT jint JNICALL Java_Main_square( JNIEnv *env, jobject obj, jint i) { return i * i; } |
编译并运行:
1 2 3 4 5 6 7 | 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 |
输出:
1 | 4 |
在Ubuntu 14.04 AMD64上测试。还与Oracle JDK 1.8.0_45合作。
Github上的示例,供您使用。
Java程序包/文件名中的下划线必须用C函数名中的
解释:
它允许您:
- 调用Java中任意汇编代码编译动态加载的库(这里用C编写)
- 并将结果返回到Java中
这可用于:
- 使用更好的CPU汇编指令(非CPU可移植)在关键部分上更快地编写代码
- 直接进行系统调用(不可移植操作系统)
以较低的可移植性为代价。
你也可以从C调用Java,但是你必须首先在C中创建一个JVM:如何从C++调用Java函数?
Android NDK
在本文中,这个概念完全相同,只是您必须使用android样板文件来设置它。
官方的NDK存储库包含"规范"示例,如Hello JNI应用程序:
- http://Github.com/GooGeLAMAMPLE/Android NDK/BLUB/4DF5A705E78A0818C6B2DBC26B8E315D89D307/你好JNI/APP/SRC/MON/Java/COM/Simult/HeloLjNi/HeloLjNi Java JavaL39
- https://github.com/googlesamples/android ndk/blob/4df5a2705e471a0818c6b2db26b8e315d89d307/hello jni/app/src/main/cpp/hello jni.c_l27
在android o上使用ndk的
ToDO确认:此外,EDCOX1(5)表示它是一个共享库,我认为它是AOT预编译的.DEX对应于ART中的Java文件,也可以看到:Android中的ODEX文件是什么?那么,Java也可能是通过EDCOX1的6接口来运行的吗?
OpenJDK 8中的示例
让我们找到JDK8U60-B27中定义
我们将得出结论,它是通过
首先我们发现:
1 |
它引导我们进入JDK/SRC/Stuty/Case/Java/Lang/Objava.JavaSyL212:
1 |
现在是最困难的部分,找到克隆人在所有间接过程中的位置。帮助我的问题是:
1 | find . -iname object.c |
它会找到C或C++文件,这些文件可能实现对象的本机方法。它将我们引入JDK/Stase/NET/Java/Lang/Objult.C.L.L47:
1 2 3 4 5 6 7 8 9 10 11 | 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])); } |
这就引出了
1 | grep -R JVM_Clone |
这将我们引向hotspot/src/share/vm/prims/jvm.cpp_l580:
1 2 | JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle)) JVMWrapper("JVM_Clone"); |
在扩展了一堆宏之后,我们得出结论,这就是定义点。
将EDCOX1的0个关键字应用于一个方法,以表明该方法是使用JNI(Java本机接口)在本机代码中实现的。
直接从Java语言规范:
A method that is
native is implemented in platform-dependent code, typically written in another programming language such as C, C++, FORTRAN,or assembly language. The body of anative method is given as a semicolon only, indicating that the implementation is omitted, instead of a block.
斯莱克斯回答说,
GWT还使用它来实现JavaScript方法。
实现本机代码的函数被声明为本机。
The Java Native Interface (JNI) is a programming framework that enables Java code running in a Java Virtual Machine (JVM) to call, and to be called by, native applications (programs specific to a hardware and operating system platform) and libraries written in other languages such as C, C++ and assembly.
http://en.wikipedia.org/wiki/java_原生_界面
本机是非访问修饰符。它只能应用于方法。它表示方法或代码的依赖平台的实现。
- EDCOX1×6是Java中的关键字,它指示平台依赖性。
- EDCX1 6种方法是Java(JNI)与其他编程语言之间的接口。
本机是Java中的一个关键字,用于将未实现的结构(方法)抽象为抽象的,但它将是一个依赖于本地的代码,如本地代码和从本地堆栈执行而不是Java堆栈。