【JNI编程】启动篇

230 阅读4分钟

JNI是一个本地编程接口。它允许在Java虚拟机(VM)中运行的Java代码与用其他编程语言(如C、C++和汇编)编写的应用程序和库进行互操作。

JNI最重要的优点是它不限制底层JVM的实现。因此,JVM供应商可以添加对JNI的支持,而不会影响JVM的其他部分。程序员可以编写本地应用程序或库的一个版本,并期望它与支持JNI的所有JVM一起工作。

一、JNI综述

虽然可以完全使用Java编写应用程序,但在某些情况下,Java本身无法满足应用程序的需求。当应用程序不能完全用Java编写时,程序员使用JNI编写Java本地方法来处理这些情况。

下面的例子说明了什么时候需要使用Java原生方法:

  • 标准Java类库不支持应用程序所需的依赖于平台的特性。
  • 已经有了一个用另一种语言编写的库,我们希望Java代码可以通过JNI访问它。
  • 希望在较低级别的语言(如汇编语言)中实现一小部分时间敏感的代码。
  • 通过JNI编程,可以使用的本地方法:
  1. 创建、检查和更新Java对象(包括数组和字符串)。
  2. 调用Java方法。
  3. 捕获和抛出异常。
  4. 加载类并获取类信息。
  5. 执行运行时类型检查。

我们还可以使用JNI和调用API来支持任意的本地应用程序嵌入JVM。这允许程序员轻松地使他们现有的应用程序启用java,而不必链接到VM源代码。

二、历史背景

来自不同供应商的VM提供不同的本地方法接口。这些不同的接口迫使程序员在给定的平台上生成、维护和分发本地方法库的多个版本。

简要介绍了一些本地方法接口,例如:

  • JDK 1.0原生方法接口
  • Netscape的Java运行时接口
  • 微软的原始本地接口和Java/COM接口

三、目标

一个统一的、经过深思熟虑的标准接口为每个人提供了以下好处:

  • 每个VM供应商都可以支持更多的本地代码。
  • 工具构建器不必维护不同种类的本地方法接口。
  • 应用程序程序员将能够编写一个版本的本地代码,这个版本将在不同的VM上运行。

标准的原生方法接口必须满足以下要求:

1.二进制兼容性——主要目标是在给定平台上跨所有Java

2.VM实现的本机方法库的二进制兼容性。对于给定的平台,程序员应该只维护本地方法库的一个版本。

3.效率——为了支持时间敏感型代码,本地方法接口必须施加很少的开销。所有已知的确保VM独立性(以及二进制兼容性)的技术都会带来一定的开销。我们必须在效率和虚拟机独立性之间达成妥协。

4.功能——接口必须公开足够的JVM内部,以允许本地方法完成有用的任务。

四、JNI编程

本地方法程序员应该面向JNI编程。面向JNI编程使程序员免受未知因素的影响,比如最终用户可能正在运行的供应商的VM。通过遵循JNI标准,将为本地库提供在给定JVM中运行的最佳机会。

如果正在实现JVM,那么应该实现JNI。JNI经过了时间测试,确保不会对VM实现施加任何开销或限制,包括对象表示、垃圾收集方案等。

五、副作用

一旦使用JNI,JAVA程序就丧失了JAVA平台的两个优点:

  • 程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。
  • 程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,你应该让本地方法集中在少数几个类当中。这样就降低了JAVA和本地代码之间的耦合性。

六、变更

从Java SE 6.0开始,已经删除了不赞成使用的结构JDK1_1InitArgs和JDK1_1AttachArgs,取而代之的是使用JavaVMInitArgs和JavaVMAttachArgs。