01-导言

上一篇:


        本章介绍 Java 本地接口 (Java Native Interface,JNI)。JNI 是一种本地编程接口。它允许在 Java 虚拟机 (VM) 内运行的 Java 代码与 C、C++ 和汇编等其他编程语言编写的应用程序和库进行互操作。

        JNI 最重要的优点是,它对底层 Java VM 的实现没有任何限制。因此,Java 虚拟机供应商可以添加对 JNI 的支持,而不会影响虚拟机的其他部分。程序员只需编写一个版本的本地应用程序或库,就能在所有支持 JNI 的 Java 虚拟机上运行

1.1 Java 本地接口概述

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

        下面的示例说明了何时需要使用 Java 本地方法:

                ①. 标准 Java 类库不支持应用程序所需的平台相关功能

                ②. 已经有了一个用其他语言编写的库,希望通过 JNI 使 Java 代码可以访问它

                ③. 想用汇编等低级语言实现一小部分运行效率高的代码

        通过 JNI 编程,可以使用本地native方法进行以下操作

                ①. 创建、检查和更新 Java 对象(包括数组和字符串)

                ②. 调用 Java 方法

                ③. 捕捉并抛出异常

                ④. 加载classes并获取class信息。

                ⑤. 执行运行时类型检查。

        还可以将 JNI 与调用 API 结合使用,使任意本地应用程序都能嵌入 Java 虚拟机。这样,程序员就可以轻松地使其现有应用程序支持 Java,而无需链接 VM 源代码。

1.2 历史背景

        不同供应商的虚拟机提供不同的本地方法接口。这些不同的接口迫使程序员在特定平台上制作、维护和发布多个版本的本地方法库。

        我们将简要介绍一些本地方法接口,例如:JDK 1.0 本地方法接口,Netscape的 Java 运行时接口,微软原始本地接口和 Java/COM 接口;

1.2.1 JDK 1.0 本地方法接口

        JDK 1.0 带有一个本地方法接口。遗憾的是,有两个主要原因导致该接口不适合其他 Java 虚拟机采用。

        首先,本地代码将 Java 对象中的字段作为 C 结构的成员进行访问。但是,Java 语言规范并未定义对象在内存中的布局方式如果 Java 虚拟机在内存中以不同方式布局对象,那么程序员就必须重新编译本地方法库

        其次,JDK 1.0 的本地方法接口依赖于保守的垃圾回收器。例如,不受限制地使用 <unhand> 宏,就必须保守地扫描本地堆栈。

1.2.2 运行时接口

        Netscape公司提出了 Java 运行时接口(JRI),这是 Java 虚拟机所提供服务的通用接口。JRI 在设计时考虑到了可移植性:它几乎不假定底层 Java 虚拟机的实现细节。JRI 解决了广泛的问题,包括:本地方法、调试、反射、嵌入(调用)等。

1.2.3 原始本地接口和 Java/COM 接口

        Microsoft Java 虚拟机支持两个本地方法接口。在底层,它提供了一个高效的原始本地接口(RNI)。RNI 与 JDK 的本地方法接口具有高度的源代码级向后兼容性,但有一个主要区别。本地代码必须使用 RNI 函数与垃圾回收器进行显式交互,而不是依赖于保守的垃圾回收。

        在更高层次上,微软的 Java/COM 接口为 Java 虚拟机提供了一个独立于语言的标准二进制接口。Java 代码可以像使用 Java 对象一样使用 COM 对象。Java 类也可以作为 COM 类暴露给系统的其他部分。

1.3 目标

        一个统一的、经过深思熟虑的标准接口能为每个人带来以下好处:

                ①. 每个虚拟机供应商都能支持更多的本地代码。

                ②. 工具构建者无需维护不同类型的本地方法接口。

                ③. 应用程序编程人员可以编写一个版本的本地代码该版本将在不同的虚拟机上运行

        实现标准本地方法接口的最佳途径是让所有对 Java 虚拟机感兴趣的各方都参与进来。因此,我们组织 Java 许可证持有者就统一本地方法接口的设计进行了一系列讨论。讨论结果表明,标准本地方法接口必须满足以下要求:

                ①.二进制兼容性:主要目标是在特定平台的所有 Java VM 实现中实现本地方法库的二进制兼容性。程序员只需为特定平台维护一个版本的本地方法库。

                ②. 效率:为了支持时间关键型代码,本地方法接口必须只产生少量开销。所有已知的确保虚拟机独立性(从而确保二进制兼容性)的技术都会带来一定的开销。我们必须在效率和虚拟机独立性之间达成某种折中

                ③. 功能性:接口必须暴露足够的 Java 虚拟机内部结构,以允许本地方法完成有用的任务

1.4 Java 本地接口方法

        我们希望采用现有方法中的一种作为标准接口,因为这将给程序员带来最小的负担,因为他们必须在不同的虚拟机中学习多个接口。遗憾的是,现有的解决方案在实现我们的目标方面都不尽如人意。

        Netscape 的 JRI 与我们设想的可移植本地方法接口最为接近,因此被用作我们设计的出发点。熟悉 JRI 的读者会发现,API 的命名约定、方法和字段 ID 的使用、局部引用和全局引用的使用等方面都有相似之处。尽管我们已经尽了最大努力,但 JNI 与 JRI 仍然不兼容,尽管虚拟机可以同时支持 JRI 和 JNI。

        微软的 RNI 是对 JDK 1.0 的改进,因为它解决了本地方法与非保守垃圾收集器一起工作的问题。然而,RNI 并不适合作为独立于虚拟机的本地方法接口。与 JDK 一样,RNI 本地方法将 Java 对象作为 C 结构访问,这导致了两个问题:

                ①. RNI 将内部 Java 对象的布局暴露给本地代码。

                ②. 将 Java 对象作为 C 结构直接访问,就不可能有效地加入 "写入障碍",而 "写入障碍 "是高级垃圾回收算法所必需的。

        作为一种二进制标准,COM 可确保不同虚拟机之间的二进制完全兼容。调用 COM 方法只需间接调用,开销很小。此外,与动态链接库相比,COM 对象在解决版本问题方面有很大改进。

        然而,使用 COM 作为标准 Java 本地方法接口会受到一些因素的影响:

                ①. 首先,Java/COM 接口缺乏某些所需的功能,如访问私有字段和引发一般异常。

                ②. 其次,Java/COM 接口会自动为 Java 对象提供标准的 IUnknown 和 IDispatch COM 接口,这样本地代码就可以访问公共方法和字段。遗憾的是,IDispatch 接口不处理重载 Java 方法,而且在匹配方法名称时不区分大小写。此外,通过 IDispatch 接口暴露的所有 Java 方法都会被封装,以执行动态类型检查和强制转换。这是因为 IDispatch 接口在设计时考虑到了弱类型语言(如 Basic)。

                ③. 第三,COM 的设计目的不是处理单个低级功能,而是让软件组件(包括成熟的应用程序)协同工作。我们认为,将所有 Java 类或低级本地方法都视为软件组件是不合适的。

                ④. 第四,由于 UNIX 平台缺乏对 COM 的支持,COM 无法立即得到采用。

        虽然 Java 对象不能像 COM 对象一样暴露在本地代码中,但 JNI 接口本身与 COM 二进制兼容。JNI 使用与 COM 相同的跳转表结构和调用约定。这意味着,一旦 COM 的跨平台支持可用,JNI 就可以成为 Java VM 的 COM 接口。

        据信,JNI 并非特定 Java 虚拟机支持的唯一本地方法接口。标准接口有利于将本地代码库加载到不同 Java 虚拟机中的程序员。在某些情况下,程序员可能必须使用较低级的、特定于 VM 的接口才能达到最高效率。在其他情况下,程序员可能会使用更高级别的接口来构建软件组件。事实上,随着 Java 环境和组件软件技术的日益成熟,本地方法将逐渐失去其重要性

1.5 根据 JNI 编程

        本地方法程序员应根据 JNI 进行编程。按照 JNI 编程可以使您免受未知因素的影响,例如:最终用户可能运行的供应商虚拟机。通过遵守 JNI 标准,你将为本地库提供在特定 Java VM 中运行的最佳机会

        如果要实现 Java 虚拟机,就应该实现 JNI。JNI 已经过时间测试,确保不会对VM 实现造成任何开销或限制,包括对象表示法、垃圾回收方案等。


下一篇: 

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值