前言
今天在看HashMap源码,后来点到了Object类,看到了几个native标识的方法,不懂,就先把native方法科普一下,先搞定了,明天再补上HashMap的分析。
native方法称为本地方法。在java源程序中以关键字“native”声明,不提供函数体。其实现使用C/C++语言在另外的文件中编写,编写的规则遵循Java本地接口的规范Java native Interface(简称JNI)。简而言就是Java中声明的可调用的使用C/C++实现的方法。
具体实现
编写有natives声明的方法的java类
不多说,代码如下
package local.zcw.demo; /** * 作者 zcw * 时间 2017/10/24 18:04 * 版本 1.0.0 * 描述 TODO */ public class MyNative { static { System.loadLibrary("MyNative"); } public static native void sayHello(); public static void main(String[] args) { MyNative.sayHello(); } }
使用javac命令编译java类
cd src/ javac local/zcw/demo/MyNative.java
使用javah -jni 命令生成*.h头文件
javah -jni local.zcw.demo.MyNative
生成的文件内容如下
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class local_zcw_demo_MyNative */ #ifndef _Included_local_zcw_demo_MyNative #define _Included_local_zcw_demo_MyNative #ifdef __cplusplus extern "C" { #endif /* * Class: local_zcw_demo_MyNative * Method: sayHello * Signature: ()V */ JNIEXPORT void JNICALL Java_local_zcw_demo_MyNative_sayHello (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
使用c语言实现本地方法
#include "jni.h" #include "local_zcw_demo_MyNative.h" #include <stdio.h> JNIEXPORT void JNICALL Java_local_zcw_demo_MyNative_sayHello(JNIEnv * env, jclass obj) { printf("hello by c\n"); }
将本地方法编写的文件生成动态链接库
gcc -dynamiclib -I ${JAVA_HOME}/include/ \ -I ${JAVA_HOME}/include/darwin/ \ local_zcw_demo_MyNative.c \ -o libMyNative.jnilib
运行
java local.zcw.demo.MyNative
其它
项目目录如下图,代码下载
完整的命令如下图
参考文章
补充(Linux下使用jni 2017/12/19)
linux下编译动态库
gcc -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux \ -fPIC -shared -o libMyNative.so \ local_zcw_demo_MyNative.c
运行
直接执行
java local.zcw.demo.MyNative
抛出java.lang.UnsatisfiedLinkError异常
可指明共享库路径
java -Djava.library.path='.' local.zcw.demo.MyNative
或添加环境变量
export LD_LIBRARY_PATH="libMyNative.so路径":$LD_LIBRARY_PATH