JNI概述

JNI是Java Native Interface的缩写,译为Java本地接口。通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。

从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。

使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java虚拟机环境。

介绍

SUN公司发布的Java 本地接口(JNI)提供了将Java与C/C++、汇编等本地代码集成的方案,该规范使得在 Java 虚拟机内运行的 Java 代码能够与其它编程语言互相操作,包括创建本地方法、更新Java对象、调用Java方法,引用 Java类,捕捉和抛出异常等,也允许 Java代码调用 C/C++或汇编语言编写的程序和库。作为一个标准程序接口,它没有对底层 Java虚拟机的实现施加任何限制,并具有以下特点:

  1. 二进制兼容。本地方法库与同一平台上所有Java 虚拟机之间实现二进制兼容,即对于给定平台开发人员只需要维护一种版本的本地方法库。
  2. 效率高。为了实现实时系统,JNI 在效率与虚拟机无关性之间进行了优化,以保障高效运行。
  3. 功能强。JNI 提供了大量的函数及接口让本地方法与Java虚拟机内核相互操作,增强两者的功能。
  4. 本地代码与 Java 虚拟机之间是通过 JNI 函数实现相互操作的。JNI 函数通过接口指针来获得,本地方法将 JNI 接口指针当作参数来接受。虚拟机保证在从相同的 Java 线程中对本地方法进行多次调用时,传递给本地方法的接口指针是相同的,本地方法被不同的 Java 线程调用时,它接受不同的 JNI接口指针。

JNI的演化

JDK1.0包含了一个本地方法接口,它允许JAVA程序调用C/C++写的程序,许多第三方的程序和JAVA类库。如:java.lang,java.io,java.net等都依赖于本地方法来访问底层系统环境的特征。不幸的是,JDK1.0中的本地方法有两个主要问题:

  1. 本地方法想访问C中的结构(structures)一样访问对象中的字段。尽管如此,JVM规范并没有定义对象怎么样在内存中实现。如果一个给定的JVM实现布局对象时,和本地方法假设的不一样,那你就不得不重新编写本地方法库。
  2. 因为本地方法可以保持对JVM中对象的直接指针,所以,JDK1.0中的本地方法采用了一种保守的GC策略。

JNI的诞生就是为了解决这两个问题,它可以被所有平台下的JVM支持:

  1. 每一个JVM实现方案可以支持大量的本地代码。
  2. 开发工具作者不必处理不同的本地方法接口。
  3. 本地代码可以运行在不同的JVM上面。

JDK1.1中第一次支持JNI,但是,JDK1.1仍在使用老风格的本地代码来实现JAVA的API。这种情况在JDK1.2下被彻底改变成符合标准的写法。

JNI的应用

当出现一些Java 无法处理的任务时,开发人员就可以使用JNI技术来完成。一般有如下情形:

  1. 需要调用Java语言不支持的依赖于操作系统平台的特性的一些功能。例如需要调用UNIX系统的某个功能,而Java不支持这个功能,就需要用到JNI技术来实现。
  2. 为了整合一些以前的非Java语言开发的系统。例如早期使用C/C++实现的功能或系统,需要将这些功能整合到当前的系统或新版本中。
  3. 为了提高程序的运行效率,需要使用C/C++语言的情况。例如:游戏、音视频开发的编解码和图像绘制。