用native修饰符修饰的方法是本地方法。native修饰符一般用来声明用其他语言书写方法体、并具体实现方法功能的特殊方法。这里的其他语言包括C、C++、Fortran、汇编语言等。由于native方法的方法体是用其他语言在程序外部写成,所以所有的native方法都没有方法体,而用一个分号代替。 为了支持native方法,Java提供了JNI软件工具,JNI是Java Native Interface的缩写。从Java 1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。 用其他语言编写类方法的目的在于:充分利用已存在的程序功能模块,并避免重复工作。由于Java是解释型语言,它的运行速度不可能很快。在某些实时性比较强或执行效率要求比较高的场合,就可以利用native方法来求助于其他运行速度较高的语言。 下面我们以一个例子,说明如何使用其他语言编写的程序,这里以C语言为例。 (1)编写java程序,在java程序中加入本地方法说明: public native void 方法名(); 不妨仍然使用HelloWorld,如下所示。 class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[ ] args) {
new HelloWorld().displayHelloWorld();
}
} 这部分内容是选学内容,读者可以略去不看。 在程序中,声明了一个displayHelloWorld的native方法,它是一个空方法;还利用静态初始化器加载了一个动态库(System.loadLibrary("hello");)。因为方法displayHelloWorld()并没有实现,但是在下面在main方法中就直接使用了,所以必须在使用前对它进行初始化。加载动态库就是实现这个目的,“hello”是动态库的名字。 (2)编译程序: javac HelloWorld.java (3)生成扩展名为.h的头文件: javah –jni 类名 这里是: javah -jni HelloWorld 其中头文件HelloWorld.h的内容如下: /* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif 可以这样理解:这个.h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致)。 (4)编写本地方法,实现和由javah命令生成的头文件里面声明的方法名相同的方法。本地方法在C语言中的方法名为: Java_ClassName _methodName (JNIEnv *env, jobject obj,……) 代码如下: #include "jni.h"
#include "HelloWorld.h"
#include JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world!/n");
return;
} 注意代码2中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入。然后保存为HelloWorldImpl.c就可以了。 (5)将头文件和(本地方法)实现文件编译成共享库文件,生成动态库。 这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用VC的编译器cl成: cl -I%java_home%/include -I%java_home%/include/win32 -LD HelloWorldImp.c -Fehello.dll 注意:生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。当然这里修改之后那里也需要修改。另外需要将-I%java_home%/include -I%java_home%/include/win32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。 (6)运行程序即可: java HelloWorld |