Java本机接口规范内容 第1章:简介

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

JNI最重要的好处是它对底层Java VM的实现没有任何限制。 因此,Java VM供应商可以添加对JNI的支持,而不会影响VM的其他部分。 程序员可以编写一个本机应用程序或库的版本,并期望它可以与支持JNI的所有Java VM一起使用。

目录

Java本机接口概述

历史背景

JDK 1.0本机方法接口

Java运行时接口

原始本机接口和Java / COM接口

目标

Java本地接口方法

编程到JNI

变化


Java本机接口概述

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

以下示例说明何时需要使用Java本机方法:

  • 标准Java类库不支持应用程序所需的与平台相关的功能。
  • 您已经有一个用另一种语言编写的库,并希望通过JNI使其可以访问Java代码。
  • 您希望在较低级别的语言(如汇编语言)中实现一小部分时间关键代码。

通过JNI编程,您可以使用本机方法:

  • 创建,检查和更新Java对象(包括数组和字符串)。
  • 调用Java方法。
  • 捕获并抛出异常。
  • 加载类并获取类信息。
  • 执行运行时类型检查。

您还可以将JNI与Invocation API一起使用,以使任意本机应用程序能够嵌入Java VM。 这使程序员可以轻松地使其现有应用程序支持Java,而无需与VM源代码链接。

历史背景

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

我们简要介绍一些本机方法接口,例如:

  • JDK 1.0本机方法接口
  • Netscape的Java运行时接口
  • Microsoft的原始本机接口和Java / COM接口

JDK 1.0本机方法接口

JDK 1.0附带了本机方法接口。 不幸的是,这个接口不适合其他Java VM采用有两个主要原因。

首先,本机代码访问Java对象中的字段作为C结构的成员。 但是, Java语言规范没有定义对象在内存中的布局方式。 如果Java VM在内存中以不同方式布局对象,则程序员必须重新编译本机方法库。

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

Java运行时接口

Netscape提出了Java运行时接口(JRI),它是Java虚拟机中提供的服务的通用接口。 JRI的设计考虑了可移植性 - 它对底层Java VM中的实现细节做了很少的假设。 JRI解决了广泛的问题,包括本机方法,调试,反射,嵌入(调用)等。

原始本机接口和Java / COM接口

Microsoft Java VM支持两种本机方法接口。 在低级别,它提供了有效的原始本机接口(RNI)。 RNI提供了与JDK本机方法接口的高度源级向后兼容性,尽管它有一个主要区别。 本机代码必须使用RNI函数与垃圾收集器明确交互,而不是依赖于保守的垃圾收集。

在更高级别,Microsoft的Java / COM接口为Java VM提供了与语言无关的标准二进制接口。 Java代码可以像使用Java对象一样使用COM对象。 Java类也可以作为COM类公开给系统的其余部分。

目标

我们相信,统一,经过深思熟虑的标准界面为每个人提供以下好处:

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

实现标准本机方法接口的最佳方法是让所有各方都参与Java VM。 因此,我们在Java许可证持有者之间组织了一系列关于统一本机方法接口设计的讨论。 从讨论中可以清楚地看出,标准本机方法接口必须满足以下要求:

  • 二进制兼容性 - 主要目标是在给定平台上的所有Java VM实现中对本机方法库进行二进制兼容。 程序员应该只为给定平台维护其本机方法库的一个版本。
  • 效率 - 为了支持时间关键代码,本机方法接口必须施加很少的开销。 确保VM独立性(以及二进制兼容性)的所有已知技术都带有一定量的开销。 我们必须以某种方式在效率和VM独立性之间达成妥协。
  • 功能 - 接口必须公开足够的Java VM内部,以允许本机方法完成有用的任务。

Java本地接口方法

我们希望采用现有方法之一作为标准接口,因为这会给必须在不同VM中学习多个接口的程序员带来最小的负担。 不幸的是,现有的解决方案在实现我们的目

Netscape的JRI最接近我们想象的便携式本机方法接口,并被用作我们设计的起点。 熟悉JRI的读者会注意到API命名约定,方法和字段ID的使用,本地和全局引用的使用等方面的相似之处。 尽管我们尽最大努力,但JNI与JRI不是二进制兼容的,尽管VM可以同时支持JRI和JNI。

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

  • RNI将内部Java对象的布局暴露给本机代码。
  • 直接访问Java对象作为C结构使得无法有效地合并“写入障碍”,这在高级垃圾收集算法中是必需的。

作为二进制标准,COM确保跨不同VM的完全二进制兼容性。 调用COM方法只需要间接调用,这几乎不会产生任何开销。 此外,COM对象在解决版本问题方面比动态链接库有了很大的改进。

但是,使用COM作为标准Java本机方法接口受到以下几个因素的阻碍:

  • 首先,Java / COM接口缺少某些所需的功能,例如访问私有字段和引发一般异常。
  • 其次,Java / COM接口自动为Java对象提供标准的IUnknown和IDispatch COM接口,以便本机代码可以访问公共方法和字段。 遗憾的是,IDispatch接口不处理重载的Java方法,并且在匹配方法名称时不区分大小写。 此外,通过IDispatch接口公开的所有Java方法都被包装以执行动态类型检查和强制。 这是因为IDispatch接口在设计时考虑了弱类型语言(例如Basic)。
  • 第三,COM不是处理单独的低级功能,而是旨在允许软件组件(包括完整的应用程序)协同工作。 我们认为将所有Java类或低级本机方法视为软件组件是不合适的。
  • 第四,由于缺乏对UNIX平台的支持,因此立即采用COM受到阻碍。

虽然Java对象不作为COM对象公开给本机代码,但JNI接口本身与COM二进制兼容。 JNI使用与COM相同的跳转表结构和调用约定。 这意味着,只要跨平台支持COM,JNI就可以成为Java VM的COM接口。

JNI不被认为是给定Java VM支持的唯一本机方法接口。 标准接口使程序员受益,他们希望将本机代码库加载到不同的Java VM中。 在某些情况下,程序员可能必须使用较低级别的VM特定接口来实现最高效率。 在其他情况下,程序员可能使用更高级别的界面来构建软件组件。 实际上,随着Java环境和组件软件技术的日趋成熟,本机方法将逐渐失去意义。

编程到JNI

本机方法程序员应该编程到JNI。 对JNI进行编程可以使您免于未知,例如最终用户可能正在运行的供应商的VM。 通过遵循JNI标准,您将为本机库提供在给定Java VM中运行的最佳机会。

如果要实现Java VM,则应实现JNI。 JNI已经过时间测试,并确保不对您的VM实施施加任何开销或限制,包括对象表示,垃圾收集方案等。 如果您遇到我们可能忽略的任何问题,请将您的反馈发送给我们。

变化

从Java SE 6.0开始,已删除不推荐使用的结构JDK1_1InitArgs和JDK1_1AttachArgs,而是使用JavaVMInitArgs和JavaVMAttachArgs。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道格拉斯范朋克

播种花生牛奶自留田

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值