java native method
最近在看《深入理解Java虚拟机》,看了没几页,看到了一个以前不了解的概念:native方法。学习如下:
"A native method is a Java method whose implementation is provided by non-java code." native方法即本地方法,native方法的实现是非Java的,例如这个方法是用C/C++实现的。在Java文件中一个native方法不能有方法体,只有方法签名,类似于接口中的抽象方法,但是native关键字和abstract关键字不能同时修饰一个方法。因为如果abstract修饰的方法是要用Java语言实现的,只不过要在子类中实现,但是native方法是用非Java语言实现的,所以native和abstract是矛盾的。但是native可以和其他修饰符一起修饰方法,例如static、synchronized等。
native可以有返回值,可以返回任意Java类型,包括非基本类型,例如数组或Object类型。
如果native修饰一个方法,那么含有这个方法的类的子类可以继承这个本地方法并且可以用Java语言来重写。如果native和final一起修饰这个方法,则不可以重写,这和普通的方法相同。
众所周知Java是跨平台的,但是Java的native机制扩充了JVM,Java无法直接访问到操作系统底层(如硬件),但是C/C++在这方面具有优势,所以native方法可以在以下条件下使用:
1.使用底层的主机平台(例如直接和访问操作系统或硬件)的某个特性,而这个特性不能通过JAVA API访问
2.加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
实现步骤:
1、编写Java程序,javac编译生成.class文件;
1、用javah编译生成的class文件,产生.h头文件;
2、编写.cpp文件实现native方法,其中需要包含上述.h头文件(.h文件中又包含了JDK自带的jni.h文件);
3、将.cpp文件变异成动态链接库.dll文件;
4、在Java中调用System.loadLibrary()方法或Runtime的loafLibrary()方法加载动态链接库文件,就可以在Java中调用这个native()方法,
5、运行Java文件,运行时加参数-Djava.library.path=[dll存放的路径]。
下面是一个实例:编写一个计算两个整数和的本地方法,该本地方法使用C/C++实现。
public class Native_Method { /** * @param args */ native public int cal(int a,int b);//本地方法无方法体 static { System.loadLibrary("test"); } public static void main(String[] args) { // TODO Auto-generated method stub Native_Method nm = new Native_method(); System.out.println(nm.cal(3,5)); } }
编译:javac Native_Method.java,此时将生成Native_Method.class;
javah -jni Native_Method,此时将生成一个Native_Method.h文件。具体如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Native_method */ #ifndef _Included_Native_method #define _Included_Native_method #ifdef __cplusplus extern "C" { #endif /* * Class: Native_method * Method: cal * Signature: (II)I */ JNIEXPORT jint JNICALL Java_Native_1method_cal (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif #endif
编写Native_Method.cpp文件:
#include "Native_method.h" JNIEXPORT jint JNICALL Java_Native_1method_cal (JNIEnv *jnienv, jobject o, jint a, jint b)//实现这个方法 { return a+b; }
在DEV C++下新建一个DLL动态链接工程,取名test,将上述.cpp和.h文件加入到工程中,编译,此时会报错:找不到<jni.h>头文件,这是需要将jdk下的include文件夹包含到工程中,具体做法:右击工程,工程属性,目录/文件,包含目录文件,将jdk安装路径下的include文件夹和include文件夹下的win32文件夹加入:C:\ProgramFiles\Java\jdk1.6.0_31\include
C:\Program Files\Java\jdk1.6.0_31\include\win32
编译这个工程,此时将出现test.dll文件。
运行这个Java文件:java Native_Method -Djava.library.path=test.dll;(此处.dll文件和Java文件在同一路径下)。
出现结果8.