native 關鍵字標記方法由非 Java 代碼 (C/C++/Rust) 實現,是 Java 突破 JVM 沙箱、調用系統底層能力、複用成熟庫的關鍵橋樑。
核心機制:JNI (Java Native Interface)
- JNI 定義 Java 與本地代碼的二進制接口規範 (調用約定、類型映射、引用管理)。
- JVM 負責參數封裝、線程附着、異常傳播、GC 根掃描 (JNI 參考)。
native 方法聲明無方法體,以分號結尾;可與 static/final/synchronized 共用,不可與 abstract 共用。
標準開發流程
- Java 聲明:
public native void hello(); + static { System.loadLibrary("hello"); }
- 編譯:
javac HelloWorld.java
- 生成頭文件:
javac -h . HelloWorld (Java 8+) 或 javah -jni HelloWorld (舊版)。產生 JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv*, jobject)。
- C/C++ 實現:
#include
#include "HelloWorld.h"
#include
JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv *env, jobject obj) {
printf("Hello from C!\n");
}
- 編譯動態庫:
- Linux/macOS:
gcc -shared -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux HelloWorld.c -o libhello.so
- Windows:
cl -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -LD HelloWorld.c -Fehello.dll
- 運行:
java -Djava.library.path=. HelloWorld (或將庫放入 java.library.path 目錄)。
關鍵類型映射
| Java 類型 | JNI 類型 | C 類型 |
| boolean | jboolean | unsigned char |
| byte | jbyte | signed char |
| char | jchar | unsigned short |
| short | jshort | short |
| int | jint | int / int32_t |
| long | jlong | long long / int64_t |
| float | jfloat | float |
| double | jdouble | double |
| String | jstring | 需轉換 (GetStringUTFChars) |
| Object | jobject | opaque handle |
| int[] | jintArray | 需 GetIntArrayElements |
進階主題
- 引用管理:局部引用 (自動釋放)、全局引用 (
NewGlobalRef 手動管理)、弱全局引用。防止內存洩漏。
- 異常處理:C 拋出異常需
ThrowNew(env, clazz, msg),Java 端捕獲。
- 數組/直接緩衝區:
GetPrimitiveArrayCritical / NewDirectByteBuffer 實現零拷貝高性能數據傳輸 (Netty、LevelDB 依賴此)。
- 線程附着:本地線程調用 JNI 需
AttachCurrentThread。
現代替代方案
| 方案 | 優勢 | 適用場景 |
| JNA (Java Native Access) | 無需寫 C/C++/編譯庫,純 Java 映射 | 調用系統 API、簡單庫、快速原型 |
| JNR-FFI | 性能優於 JNA,支持動態庫熱加載 | 高性能本地交互 |
| GraalVM Native Image | AOT 編譯,Java 代碼直接編譯為本地機器碼 | 微服務啟動快、無 JNI 邊界開銷 |
| Panama (Project Panama / Java 20+) | Foreign Function & Memory API (FFM),標準化、安全、高性能 | 未來標準,替代 JNI |
JNI 功能強大但開發繁瑣、調試困難、跨平台部署痛苦。優先評估 JNA/FFM/Panama,僅在極致性能、複用核心 C++ 庫、系統級調用場景堅持使用 JNI。
- 上一篇文章: Java 8 日期時間 API (java.time) 實戰指南:20 個高頻場景代碼模板
- 下一篇文章: Java 基礎語法精要:修飾符、運算符優先級與核心特性速查表
Copyright ©
程式碼之家 All Rights Reserved