whi*_*win 455 java java-native-interface native keyword
在玩这个谜题(这是一个Java关键字琐事游戏)时,我遇到了native
关键字.
Java中的native关键字用于什么?
Cir*_*四事件 422
使事情更清晰的最小例子:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
Main.c:
#include <jni.h>
#include "Main.h"
JNIEXPORT jint JNICALL Java_Main_square(
JNIEnv *env, jobject obj, jint i) {
return i * i;
}
Run Code Online (Sandbox Code Playgroud)
编译并运行:
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
Run Code Online (Sandbox Code Playgroud)
输出:
4
Run Code Online (Sandbox Code Playgroud)
在Ubuntu 14.04 AMD64上测试.还使用了Oracle JDK 1.8.0_45.
GitHub上的示例供您玩.
必须使用_1
C函数名转义Java包/文件名中的下划线,如下所述:在包含下划线的Android包名中调用JNI函数
解释:
它允许您:
这可以用于:
与低便携性的权衡.
您也可以从C调用Java,但必须首先在C中创建JVM:如何从C++调用Java函数?
Android NDK
除了您必须使用Android样板来设置它之外,这个概念在此上下文中完全相同.
官方NDK存储库包含"规范"示例,例如hello-jni app:
在您unzip
的.apk
使用NDK Android上的O,你可以看到预编译.so
对应下的本地代码lib/arm64-v8a/libnative-lib.so
.
TODO确认:此外,file /data/app/com.android.appname-*/oat/arm64/base.odex
它说它是一个共享库,我认为是AOT预编译的.dex对应于ART中的Java文件,另请参阅:Android中的ODEX文件是什么?那么Java实际上也可以通过native
接口运行?
OpenJDK 8中的示例
让我们找到Object#clone
jdk8u60-b27中定义的位置.
我们将得出结论,它是通过native
调用实现的.
首先我们发现:
find . -name Object.java
Run Code Online (Sandbox Code Playgroud)
这导致我们jdk/src/share/classes/java/lang/Object.java#l212:
protected native Object clone() throws CloneNotSupportedException;
Run Code Online (Sandbox Code Playgroud)
现在是困难的部分,找到克隆在所有间接中的位置.帮助我的查询是:
find . -iname object.c
Run Code Online (Sandbox Code Playgroud)
可以找到可能实现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]));
}
Run Code Online (Sandbox Code Playgroud)
这导致我们的JVM_Clone
符号:
grep -R JVM_Clone
Run Code Online (Sandbox Code Playgroud)
这导致我们到hotspot/src/share/vm/prims/jvm.cpp#l580:
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
Run Code Online (Sandbox Code Playgroud)
在扩展了一堆宏之后,我们得出结论,这是定义点.
Orh*_*nar 412
它标志着一种方法,它将用其他语言实现,而不是用Java实现.它与JNI(Java Native Interface)一起使用.
过去使用本机方法来编写性能关键部分,但随着Java变得越来越快,这现在不太常见了.当时需要本机方法
您需要从Java调用用其他语言编写的库.
您需要访问只能从其他语言(通常为C)访问的系统或硬件资源.实际上,许多与真实计算机(例如磁盘和网络IO)交互的系统功能只能这样做,因为它们调用本机代码.
另请参阅 Java本地接口规范
SLa*_*aks 328
该native
关键字应用于方法,以指示该方法是使用JNI(Java Native Interface)在本机代码中实现的.
Ade*_*lin 13
实现本机代码的函数声明为native.
Java Native Interface(JNI)是一个编程框架,它使在Java虚拟机(JVM)中运行的Java代码能够调用本机应用程序(特定于硬件和操作系统平台的程序)和用库编写的库来调用.其他语言,如C,C++和汇编.
http://en.wikipedia.org/wiki/Java_Native_Interface
native
由于功能或性能原因,Java方法为 Java 代码提供了一种调用操作系统本机代码的机制。
例子:
606 public native int availableProcessors();
617 public native long freeMemory();
630 public native long totalMemory();
641 public native long maxMemory();
664 public native void gc();
Run Code Online (Sandbox Code Playgroud)
在Runtime.class
OpenJDK对应的文件中,位于 中JAVA_HOME/jmods/java.base.jmod/classes/java/lang/Runtime.class
,包含这些方法并用ACC_NATIVE
( 0x0100
)标记,并且这些方法不包含Code 属性,这意味着这些方法在Runtime.class
文件中没有任何实际的编码逻辑:
availableProcessors
:标记为 native 并且没有 Code 属性freeMemory
:标记为 native 并且没有 Code 属性totalMemory
:标记为 native 并且没有 Code 属性maxMemory
:标记为 native 并且没有 Code 属性gc
:标记为 native 并且没有 Code 属性实际上的编码逻辑在对应的Runtime.c文件中:
42 #include "java_lang_Runtime.h"
43
44 JNIEXPORT jlong JNICALL
45 Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
46 {
47 return JVM_FreeMemory();
48 }
49
50 JNIEXPORT jlong JNICALL
51 Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject this)
52 {
53 return JVM_TotalMemory();
54 }
55
56 JNIEXPORT jlong JNICALL
57 Java_java_lang_Runtime_maxMemory(JNIEnv *env, jobject this)
58 {
59 return JVM_MaxMemory();
60 }
61
62 JNIEXPORT void JNICALL
63 Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
64 {
65 JVM_GC();
66 }
67
68 JNIEXPORT jint JNICALL
69 Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
70 {
71 return JVM_ActiveProcessorCount();
72 }
Run Code Online (Sandbox Code Playgroud)
这些C
编码被编译到libjava.so
(Linux) 或libjava.dll
(Windows) 文件中,位于JAVA_HOME/jmods/java.base.jmod/lib/libjava.so
:
参考
归档时间: |
|
查看次数: |
218183 次 |
最近记录: |