What is a native implementation in Java?
如果我们查看Java Object类,那么我们可以找到一些方法,如:
1 2 |
这些本地人是什么?这些方法如何运作?
这些方法是Intrinsic或在Java之外的"本机"代码中编写,即特定于给定机器。
您提到的是Intrinsic和JDK的一部分,但您也可以使用Java Native Interface(JNI)自己编写本机方法。这通常会使用C来编写方法,但是许多其他语言(例如python)允许您以相当容易的方式编写方法。代码以这种方式编写,无论是为了提高性能,还是因为它需要访问平台特定的基础结构,而这些基础结构无法在普通java中完
在
大多数本机方法是使用JNI实现的,如其他答案中所述。
但是,性能关键方法(如
许多人会声称
本机方法主要在C中实现,并编译为直接在机器上运行的本机代码。
这与普通方法形成对比,普通方法在Java中实现并编译为Java字节代码,由Java虚拟机(JVM)执行。
要从Java接口这些方法,您需要使用Java Native Interface(JNI)。
访问低级别的东西通常需要本机代码。在hashCode的情况下,这是内存中对象的地址。我对克隆的猜测是它将原始内存从给定对象复制到克隆对象。本机代码的其他用途是用于访问OS功能或硬件。
使用本机代码的缺点是您失去了JVM的安全性,即您的程序可能会因本机代码中的错误而崩溃或出现安全漏洞。
What are these natives and how do these methods work?
使事情更清晰的最小例子:
Main.java:
1 2 3 4 5 6 7 |
MAIN.C:
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上测试过。还使用了Oracle JDK 1.8.0_45。
GitHub上的示例供您玩。
解释:
它允许您:
- 使用Java中的任意汇编代码调用已编译的动态加载库(此处用C语言编写)
- 并将结果返回Java
这可以用于:
- 使用更好的CPU汇编指令(不是CPU便携式)在关键部分编写更快的代码
- 进行直接系统调用(不是OS便携式)
与低便携性的权衡。
您也可以从C调用Java,但必须首先在C中创建JVM:如何从C ++调用Java函数?
OpenJDK 8中的示例
让我们找到jdk8u60-b27中定义
首先我们发现:
1 |
这导致我们jdk / src / share / classes / java / lang / Object.java#l212:
1 |
现在是困难的部分,找到克隆在所有间接中的位置。帮助我的查询是:
1 | find . -iname object.c |
可以找到可能实现Object的本机方法的C或C ++文件。它将我们引向jdk / share / native / java / lang / Object.c#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"); |
在扩展了一堆宏之后,我们得出结论,这是定义点。
Java中的本机方法是使用称为JNI的"Java Native Interface"实现的。