javah.exe 是 Java 开发工具包(JDK)中的一个工具,用于生成 JNI(Java Native Interface)头文件。JNI 是 Java 提供的一种机制,允许 Java 代码调用本地(C/C++)代码,以便与系统级功能进行交互。
使用 javah.exe 工具可以根据 Java 类中的 native 方法生成对应的 C/C++ 头文件,这样就可以在本地代码中实现这些 native 方法。
javah [options] <classes>
-o <file> 输出文件 (只能使用 -d 或 -o 之一)
-d <dir> 输出目录,指定生成的头文件的输出目录。
-v -verbose 启用详细输出
-h --help -? 输出此消息
-version 输出版本信息
-jni 生成 JNI 样式的标头文件 (默认值)
-force 始终写入输出文件,强制覆盖已存在的头文件。
-classpath <path> 指定 javah 工具查找类文件的路径。
-cp <path> 从中加载类的路径
-bootclasspath <path> 从中加载引导类的路径
<classes> 是使用其全限定名称指定的,例如:java.lang.Object
假设您有一个名为 HelloWorld 的 Java 类,其中包含一个 native 方法 nativeMethod,您希望生成 JNI 头文件以实现该方法的本地实现。步骤如下:
(1)编写 Java 类 HelloWorld.java:
package com.hxstrive.javah;
/**
* @author HuangXin
* @since 1.0.0 2024/2/28 13:59
*/
public class HelloWorld {
public native void nativeMethod();
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
hello.nativeMethod();
}
}(2)编译 Java 类:
E:\demo\src\main\java>javac ./com/hxstrive/javah/HelloWorld.java
(3)使用 javah 命令生成 JNI 头文件:
E:\demo\src\main\java>javah -jni com.hxstrive.javah.HelloWorld
执行上述命令后,将生成一个名为 HelloWorld.h 的头文件,其中包含了 nativeMethod 方法的声明。您可以在本地代码中实现该方法。如下图:

com_hxstrive_javah_HelloWorld.h 文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_hxstrive_javah_HelloWorld */
#ifndef _Included_com_hxstrive_javah_HelloWorld
#define _Included_com_hxstrive_javah_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_hxstrive_javah_HelloWorld
* Method: nativeMethod
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_hxstrive_javah_HelloWorld_nativeMethod
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif(4)编写本地代码 HelloWorld.c 来实现 native 方法:
#include <stdio.h>
#include <jni.h>
#include "com_hxstrive_javah_HelloWorld.h"
JNIEXPORT void JNICALL Java_com_hxstrive_javah_HelloWorld_nativeMethod(JNIEnv *_env, jobject _obj) {
// 在这里实现 nativeMethod 的本地代码
printf("Hello from JNI C code!\n");
}(5)编译本地 C 代码(注意,需要提前安装 MinGW):
E:\demo\src\main\java>gcc -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" HelloWorld.c -o HelloWorld.dll
其中:
-I"%JAVA_HOME%\include" 和 -I"%JAVA_HOME%\include\win32" 分别指定了 JDK 的头文件路径。
-shared 参数表示生成共享库文件。
在编译成功后,将生成一个名为 HelloWorld.dll 动态链接库文件。
(6)将共享库加载到 Java 程序中,并调用 nativeMethod 方法。修改一下 HelloWorld.java 程序,如下:
package com.hxstrive.javah;
public class HelloWorld {
public native void nativeMethod();
static {
// 加载共享库 HelloWorld.dll
System.loadLibrary("HelloWorld");
}
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
hello.nativeMethod();
}
}注意:运行程序前需要将 HelloWorld.dll 共享库放到 %JAVA_HOME%\bin 目录,而且还要将共享库和 JDK 版本保持一致,要么全是 32位,要么全是 64位。否则将会得到如下错误信息:
java.lang.UnsatisfiedLinkError: C:\Program Files\Java\jdk1.8.0_171\bin\HelloWorld.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at com.hxstrive.javah.HelloWorld.<clinit>(HelloWorld.java:12) Exception in thread "main"