我們打開 java 源碼進行查看時,常常可以看到有 native 修飾的方法
@HotSpotIntrinsicCandidate
public final native Class<?> getClass();
- 以上方法是來自 jdk12 中的 Object 類中的實現
- 像 java 語言是不能直接獲取到內存地址的,這個時候 java 開發者通過 native 關鍵字來調用到底層 C / C++
- 被@HotSpotIntrinsicCandidate標註的方法,在HotSpot中都有一套高效的實現,該高效實現基於CPU指令,運行時,HotSpot維護的高效實現會替代JDK的源碼實現,從而獲得更高的效率。
下面我們來通過 native 來調用一下 java 底層吧
編寫java入口程序
public class NativeMethod {
static {// 加載目錄下的 NativeMethod.dll 文件
System.loadLibrary("NativeMethod");
}
// 編寫 Native 修飾的方法
public static native void getMethod();
// 直接在 main 方法中使用 Native 方法
public static void main(String[] args) {
new NativeMethod().getMethod();
}
}
開始編譯程序
javac NativeMethod.java
通過 javah 工具生成動態鏈接庫頭文件
*.h
javah NativeMethod
通過 C 語言實現頭文件
#include "NativeMethod.h"
#include <jni.h>
#include <stdio.h>
JNIEXPORT void JNICALL Java_NativeMethod_getMethod (JNIEnv *env, jobject obj) {
printf("Hello Native!\n");
return;
}
最後通過 gcc 來編譯
*.c
文件生成*.dll
動態鏈接庫
gcc -m64 -Wl,--add-stdcall-alias -I"C:\Program Files\Java\jdk1.8.0_201\include" -I"C:\Program Files\Java\jdk1.8.0_201\include\win32" -shared -o NativeMethod.dll NativeMethod.c
- C:\Program Files\Java\jdk1.8.0_201\include 可以看到在
*.c
文件中有引入#include <jni.h>
開始運行程序就可以調用到底層了
$ java NativeMethod
Hello Native!
一共生成了哪些文件
JNI 調用 C 流程圖