Java 本地接口(Java Native Interface,JNI)。JNI 是本地编程接口。它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行互操作。
JNI 最重要的好处是它没有对底层 Java 虚拟机的实现施加任何限制。因此,Java 虚拟机厂商可以在不影响虚拟机其它部分的情况下添加对 JNI 的支持。程序员只需编写一种版本的本地应用程序或库,就能够与所有支持 JNI 的 Java 虚拟机协同工作。
本章论及以下主题:
Java 本地接口概述
背景
目标
Java 本地接口方法
利用 JNI 编程
JDK 1.1.2 中的变化
--------------------------------------------------------------------------------
Java 本地接口概述
尽管可以完全用 Java 编写应用程序,但是有时单独用 Java 不能满足应用程序的需要。程序员使用 JNI 来编写 Java 本地方法,可以处理那些不能完全用 Java 编写应用程序的情况。
以下示例说明了何时需要使用 Java 本地方法:
标准 Java 类库不支持与平台相关的应用程序所需的功能。
已经拥有了一个用另一种语言编写的库,而又希望通过 JNI 使 Java 代码能够访问该库。
想用低级语言(如汇编语言)实现一小段时限代码。
通过用 JNI 编程,可以将本地方法用于:
创建、检查及更新 Java 对象(包括数组和字符串)。
调用 Java 方法。
捕捉和抛出异常。
加载类和获得类信息。
执行运行时类型检查。
也可以与调用 API 一起使用 JNI,以答应任意本地应用程序嵌入到 Java 虚拟机中。这样使得程序员能够轻易地让已有应用程序支持 Java,而不必与虚拟机源代码相链接。
--------------------------------------------------------------------------------
背景
目前,不同厂商的虚拟机提供了不同的本地方法接口。这些不同的接口使程序员不得不在给定平台上编写、维护和分发多种版本的本地方法库。
下面简要分析一下部分已有本地方法接口,例如:
JDK 1.0 本地方法接口
Netscape 的 Java 运行时接口
Microsoft 的原始本地接口和 Java/COM 接口
JDK 1.0 本地方法接口
JDK 1.0 附带有本地方法接口。遗憾的是,有两点原因使得该接口不适合于其它 Java 虚拟机。
第一,平台相关代码将 Java 对象中的域作为 C 结构的成员来进行访问。但是,Java 语言规范没有规定在内存中对象是如何布局的。假如 Java 虚拟机在内存中布局对象的方式有所不同,程序员就不得不重新编译本地方法库。
第二,JDK 1.0 的本地方法接口依靠于保守的垃圾收集器。例如,无限制地使用 unhand 宏使得有必要以保守方式扫描本地堆栈。
Java 运行时接口
Netscape 建议使用 Java 运行时接口 (JRI),它是 Java 虚拟机所提供服务的通用接口。JRI 的设计融入了可移植性---它几乎没有对底层 Java 虚拟机的实现细节作任何假设。JRI 提出了各种各样的问题,包括本地方法、调试、反射、嵌入(调用)等等。
原始本地接口和 Java/COM 接口
Microsoft Java 虚拟机支持两种本地方法接口。在低一级,它提供了高效的原始本地接口 (RNI)。RNI 提供了与 JDK 本地方法接口有高度源代码级的向后兼容性,尽管它们之间还有一个主要区别,即平台相关代码必须用 RNI 函数来与垃圾收集器进行显式的交互,而不是依靠于保守的垃圾收集。
在高一级,Microsoft 的 Java/COM 接口为 Java 虚拟机提供了与语言无关的标准二进制接口。Java 代码可以象使用 Java 对象一样来使用 COM 对象。Java 类也可以作为 COM 类显示给系统的其余部分。
--------------------------------------------------------------------------------
目标
我们认为统一的,经过细致考虑的标准接口能够向每个用户提供以下好处:
每个虚拟机厂商都可以支持更多的平台相关代码。
工具构造器不必维护不同的本地方法接口。
应用程序设计人员可以只编写一种版本的平台相关代码就能够在不同的虚拟机上运行。
获得标准本地方法接口的最佳途径是联合所有对 Java 虚拟机有爱好的当事方。因此,我们在 Java 获得许可方之间组织了一系列研讨会,对设计统一的本地方法接口进行了讨论。从研讨会可以明确地看出标准本地方法接口必须满足以下要求:
二进制兼容性 - 主要的目标是在给定平台上的所有 Java 虚拟机实现之间实现本地方法库的二进制兼容性。