在玩这个谜题 (这是Java关键字琐事游戏)时,我遇到了native
关键字。
Java中的native关键字用于什么?
#1楼
实现本机代码的函数被声明为本机。
Java本机接口(JNI)是一个编程框架,使在Java虚拟机(JVM)中运行的Java代码能够调用本机应用程序(特定于硬件和操作系统平台的程序)和编写的库,并由它们进行调用。其他语言,例如C,C ++和汇编语言。
http://en.wikipedia.org/wiki/Java_Native_Interface
#2楼
native是java中的关键字,它用于使未实现的结构(方法)像抽象的一样,但是它将依赖于平台(例如本机代码)并从本机堆栈而不是java堆栈执行。
#3楼
NATIVE是非访问修饰符。它只能应用于METHOD。 它指示方法或代码的PLATFORM-DEPENDENT实现。
#4楼
最小的可运行示例
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一起使用。
GitHub上的示例供您使用。
Java包/文件名中的下划线必须使用C函数名中的_1
进行转义,如下所述: 在包含下划线的Android包名中调用JNI函数
释义 :
它允许您:
- 使用Java中的任意汇编代码调用已编译的动态加载的库(此处用C编写)
- 并将结果返回Java
这可以用来:
- 使用更好的CPU组装指令在关键部分上编写更快的代码(不便于CPU移植)
- 进行直接系统调用(非OS便携式)
以降低便携性为代价。
也可以从C调用Java,但是必须首先在C中创建JVM: 如何从C ++调用Java函数?
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
在Android O上使用NDK unzip
.apk
时,您可以看到预编译的.so
,它对应于lib/arm64-v8a/libnative-lib.so
下的本机代码。
TODO确认:此外, file /data/app/com.android.appname-*/oat/arm64/base.odex
表示它是一个共享库,我认为这是与ART中的Java文件相对应的AOT预编译.dex。 ,另请参阅: Android中的ODEX文件是什么? 那么也许Java实际上也通过native
接口运行?
OpenJDK 8中的示例
让我们找到在jdk8u60-b27中定义Object#clone
位置。
我们将得出结论,它是通过native
调用实现的。
首先我们发现:
find . -name Object.java
这导致我们到jdk / src / share / classes / java / lang / Object.java#l212 :
protected native Object clone() throws CloneNotSupportedException;
现在来了困难的部分,在所有间接寻址中找到克隆的位置。 帮助我的查询是:
find . -iname object.c
它将找到可能实现Object的本机方法的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");
扩展了一堆宏之后,我们得出的结论是这是定义点。
#5楼
-
native
是Java中的关键字,表示平台相关。 -
native
方法充当Java( JNI )与其他编程语言之间的接口。
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3161430