native 修飾符聲明方法由非 Java 代碼實現(通常為 C/C++),編譯為動態鏈接庫(Windows .dll, Linux .so, macOS .dylib),通過 JNI (Java Native Interface) 被 JVM 調用。
public class NativeExample {
// 聲明本地方法,無方法體,以分號結尾
public native void nativeMethod(int param);
// 靜態代碼塊加載動態庫
static {
System.loadLibrary("NativeExample"); // 加載 libNativeExample.so / NativeExample.dll
}
public static void main(String[] args) {
new NativeExample().nativeMethod(42);
}
}
native 方法,編譯 javac NativeExample.java。javac -h . NativeExample.java (JDK 8+) 或 javah NativeExample (舊版)。JNIEXPORT void JNICALL Java_NativeExample_nativeMethod(JNIEnv *env, jobject obj, jint param)。gcc -shared -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux NativeExample.c -o libNativeExample.socl /I"%JAVA_HOME%\include" /I"%JAVA_HOME%\include\win32" NativeExample.c /LD /FeNativeExample.dlljava.library.path 路徑下。| 場景 | 說明 | 典型例子 |
|---|---|---|
| 系統底層調用 | 文件鎖、進程管理、硬件訪問、高精度計時 | FileChannel.lock(), System.nanoTime() |
| 性能熱點優化 | 密集計算、圖像處理、加密算法、矩陣運算 | OpenCV Java 綁定、Netty JNI Transport、LevelDB/RocksDB Java 客戶端 |
| 復用現有 C/C++ 庫 | 避免重寫成熟庫(視頻編解碼、數據庫引擎、科學計算) | FFmpeg、SQLite、TensorFlow C API、Bullet Physics |
| 跨語言互操作 | 與 C++/Rust/Go 共享內存、傳遞指針 | JNI、JNA、GraalVM Native Image、Panama Foreign Function API (JEP 419+) |
GetFieldID, GetIntField, SetObjectFieldGetMethodID, CallVoidMethod, CallStaticIntMethodNewStringUTF, GetStringUTFChars, ReleaseStringUTFCharsGetArrayLength, GetIntArrayElements, ReleaseIntArrayElementsThrowNew, ExceptionCheck, ExceptionClearNewGlobalRef, DeleteGlobalRef, NewWeakGlobalRefJNIEnv* 綁定調用線程,跨線程傳遞需 AttachCurrentThread/DetachCurrentThread。GetPrimitiveArrayCritical (慎用)。CLinker)。Linker.nativeLinker().downcallHandle() 直接調用外部函數,MemorySegment 管理堆外內存,將替代 JNI/JNA 成為標準。private,對外暴露 Java 包裝方法,封裝異常轉換、資源釋放。UnsatisfiedLinkError 捕獲)。JNIEnv* 返回值,防止崩潰傳播到 JVM。nar-maven-plugin, cpp-gradle-plugin),實現跨平台自動編譯打包。native 是 Java 通往系統底層與異語言生態的橋樑,理解 JNI 機制與現代替代方案,能在性能極致化、庫復用、跨語言互操作場景做出正確技術選型。