您好,欢迎访问三七文档
当前位置:首页 > 财经/贸易 > 资产评估/会计 > 15Java本地接口规范
Java本地接口规范Java本地接口规范1997年5月16日目录1.简介Java本地接口概述背景JDK1.0本地方法接口Java运行时接口原始本地接口和Java/COM接口目标Java本地接口方法利用JNI编程JDK1.1.2中的变化2.设计概述JNI接口函数和指针加载和链接本地方法解析本地方法名本地方法的参数引用Java对象全局和局部引用实现局部引用访问Java对象访问基本类型数组访问域和方法报告编程错误Java异常异常和错误代码异步异常异常的处理3.JNI的类型和数据结构基本类型引用类型域ID和方法ID值类型类型签名UTF-8字符串4.JNI函数接口函数表版本信息GetVersion类操作DefineClassFindClassGetSuperclassIsAssignableFrom异常ThrowThrowNewExceptionOccurredExceptionDescribeExceptionClearFatalError全局及局部引用NewGlobalRefDeleteGlobalRefDeleteLocalRef对象操作AllocObjectGetObjectClassIsInstanceOfIsSameObject访问对象的域GetFieldIDGettypeField例程SettypeField例程调用实例方法GetMethodIDCalltypeMethodCallNonvirtualtypeMethod访问静态域GetStaticFieldIDGetStatictypeField例程SetStatictypeField例程调用静态方法GetStaticMethodIDCallStatictypeMethod字符串操作NewStringGetStringLengthGetStringCharsReleaseStringCharsNewStringUTFGetStringUTFLengthGetStringUTFCharsReleaseStringUTFChars数组操作GetArrayLengthNewObjectArrayGetObjectArrayElementSetObjectArrayElementNewPrimitiveTypeArray例程GetPrimitiveTypeArrayElements例程ReleasePrimitiveTypeArrayElements例程GetPrimitiveTypeArrayRegion例程SetPrimitiveTypeArrayRegion例程注册本地方法RegisterNativesUnregisterNatives监视程序操作MonitorEnterMonitorExitJava虚拟机接口GetJavaVM5.调用API概述创建虚拟机连接虚拟机卸载虚拟机初始化结构调用API函数JNI_GetDefaultJavaVMInitArgsJNI_GetCreatedJavaVMsJNI_CreateJavaVMDestroyJavaVMAttachCurrentThreadDetachCurrentThread1-简介本章介绍Java本地接口(JavaNativeInterface,JNI)。JNI是本地编程接口。它使得在Java虚拟机(VM)内部运行的Java代码能够与用其它编程语言(如C、C++和汇编语言)编写的应用程序和库进行互操作。JNI最重要的好处是它没有对底层Java虚拟机的实现施加任何限制。因此,Java虚拟机厂商可以在不影响虚拟机其它部分的情况下添加对JNI的支持。程序员只需编写一种版本的本地应用程序或库,就能够与所有支持JNI的Java虚拟机协同工作。本章论及以下主题:Java本地接口概述背景目标Java本地接口方法利用JNI编程JDK1.1.2中的变化Java本地接口概述尽管可以完全用Java编写应用程序,但是有时单独用Java不能满足应用程序的需要。程序员使用JNI来编写Java本地方法,可以处理那些不能完全用Java编写应用程序的情况。以下示例说明了何时需要使用Java本地方法:标准Java类库不支持与平台相关的应用程序所需的功能。已经拥有了一个用另一种语言编写的库,而又希望通过JNI使Java代码能够访问该库。想用低级语言(如汇编语言)实现一小段时限代码。通过用JNI编程,可以将本地方法用于:创建、检查及更新Java对象(包括数组和字符串)。调用Java方法。捕捉和抛出异常。加载类和获得类信息。执行运行时类型检查。也可以与调用API一起使用JNI,以允许任意本地应用程序嵌入到Java虚拟机中。这样使得程序员能够轻易地让已有应用程序支持Java,而不必与虚拟机源代码相链接。背景目前,不同厂商的虚拟机提供了不同的本地方法接口。这些不同的接口使程序员不得不在给定平台上编写、维护和分发多种版本的本地方法库。下面简要分析一下部分已有本地方法接口,例如:JDK1.0本地方法接口Netscape的Java运行时接口Microsoft的原始本地接口和Java/COM接口JDK1.0本地方法接口JDK1.0附带有本地方法接口。遗憾的是,有两点原因使得该接口不适合于其它Java虚拟机。第一,平台相关代码将Java对象中的域作为C结构的成员来进行访问。但是,Java语言规范没有规定在内存中对象是如何布局的。如果Java虚拟机在内存中布局对象的方式有所不同,程序员就不得不重新编译本地方法库。第二,JDK1.0的本地方法接口依赖于保守的垃圾收集器。例如,无限制地使用unhand宏使得有必要以保守方式扫描本地堆栈。Java运行时接口Netscape建议使用Java运行时接口(JRI),它是Java虚拟机所提供服务的通用接口。JRI的设计融入了可移植性---它几乎没有对底层Java虚拟机的实现细节作任何假设。JRI提出了各种各样的问题,包括本地方法、调试、反射、嵌入(调用)等等。原始本地接口和Java/COM接口MicrosoftJava虚拟机支持两种本地方法接口。在低一级,它提供了高效的原始本地接口(RNI)。RNI提供了与JDK本地方法接口有高度源代码级的向后兼容性,尽管它们之间还有一个主要区别,即平台相关代码必须用RNI函数来与垃圾收集器进行显式的交互,而不是依赖于保守的垃圾收集。在高一级,Microsoft的Java/COM接口为Java虚拟机提供了与语言无关的标准二进制接口。Java代码可以象使用Java对象一样来使用COM对象。Java类也可以作为COM类显示给系统的其余部分。目标我们认为统一的,经过细致考虑的标准接口能够向每个用户提供以下好处:每个虚拟机厂商都可以支持更多的平台相关代码。工具构造器不必维护不同的本地方法接口。应用程序设计人员可以只编写一种版本的平台相关代码就能够在不同的虚拟机上运行。获得标准本地方法接口的最佳途径是联合所有对Java虚拟机有兴趣的当事方。因此,我们在Java获得许可方之间组织了一系列研讨会,对设计统一的本地方法接口进行了讨论。从研讨会可以明确地看出标准本地方法接口必须满足以下要求:二进制兼容性-主要的目标是在给定平台上的所有Java虚拟机实现之间实现本地方法库的二进制兼容性。对于给定平台,程序员只需要维护一种版本的本地方法库。效率-若要支持时限代码,本地方法接口必须增加一点系统开销。所有已知的用于确保虚拟机无关性(因而具有二进制兼容性)的技术都会占用一定的系统开销。我们必须在效率与虚拟机无关性之间进行某种折衷。功能-接口必须显示足够的Java虚拟机内部情况以使本地方法能够完成有用的任务。Java本地接口方法我们希望采用一种已有的方法作为标准接口,因为这样程序员(程序员不得不学习在不同虚拟机中的多种接口)的工作负担最轻。遗憾的是,已有解决方案中没有任何方案能够完全地满足我们的目标。Netscape的JRI最接近于我们所设想的可移植本地方法接口,因而我们采用它作为设计起点。熟悉JRI的读者将会注意到在API命名规则、方法和域ID的使用、局部和全局引用的使用,等等中的相似点。虽然我们进行了最大的努力,但是JNI并不具有对JRI的二进制兼容性,不过虚拟机既可以支持JRI,又可以支持JNI。Microsoft的RNI是对JDK1.0的改进,因为它可以解决使用非保守的垃圾收集器的本地方法的问题。然而,RNI不适合用作与虚拟机无关的本地方法接口。与JDK类似,RNI本地方法将Java对象作为C结构来访问。这将导致两个问题:RNI将内部Java对象的布局暴露给了平台相关代码。将Java对象作为C结构直接进行访问使得不可能有效地加入“写屏障”,写屏障是高级的垃圾收集算法所必需的。作为二进制标准,COM确保了不同虚拟机之间的完全二进制兼容性。调用COM方法只要求间接调用,而这几乎不会占用系统开销。另外,COM对象对动态链接库解决版本问题的方式也有很大的改进。然而,有几个因素阻碍了将COM用作标准Java本地方法接口:第一,Java/COM接口缺少某些必需功能,例如访问私有域和抛出普通异常。第二,Java/COM接口自动为Java对象提供标准的IUnknown和IDispatchCOM接口,因而平台相关代码能够访问公有方法和域。遗憾的是,IDispatch接口不能处理重载的Java方法,而且在匹配方法名称时不区别大小写。另外,通过IDispatch接口暴露的所有Java方法被打包在一起来执行动态类型检查和强制转换。这是因为IDispatch接口的设计只考虑到了弱类型的语言(例如Basic)。第三,COM允许软件组件(包括完全成熟的应用程序)一起工作,而不是处理单个低层函数。我们认为将所有Java类或低层本地方法都当作软件组件是不恰当的。第四,在UNIX平台上由于缺少对COM的支持,所以阻碍了直接采用COM。虽然我们没有将Java对象作为COM对象暴露给平台相关代码,但是JNI接口自身与COM具有二进制兼容性。我们采用与COM一样的跳转表和调用约定。这意味着,一旦具有对COM的跨平台支持,JNI就能成为Java虚拟机的COM接口。我们认为JNI不应该是给定Java虚拟机所支持的唯一的本地方法接口。标准接口的好处在于程序员可以将自己的平台相关代码库加载到不同的Java虚拟机上。在某些情况下,程序员可能不得不使用低层且与虚拟机有关的接口来获得较高的效率。但在其它情况下,程序员可能使用高层接口来建立软件组件。实际上,我们希望随着Java环境和组件软件技术发展得越来越成熟,本地方法将变得越来越不重要。利用JNI编程本地方法程序设计人员应开始利用JNI进行编程。利用JNI编程隔离了一些未知条件,例如终端用户可能正在运行的厂商的虚拟机。遵守JNI标准是本地库能在给定Java虚拟机上运行的最好保证。例如,虽然JDK1.1将继续支持JDK1.0中所实现的旧式的本地方法接口,但是可以肯定的是JDK的未来版本将停止支持旧式的本地方法接口。依赖于旧式接口的本地方法将不得不重新编写。如果您正在实现Java虚拟机,则应该实现JNI。我们(Javasoft和获得许可方)尽力确保JNI不会占用虚拟机实现的系统开销或施加任何限制,包括对象表示,垃圾收集机制等。如果您遇到了我们可能忽视了的问题,请告知我们。JDK1.1.2中的变化为了更好地支持Java运行时环境(JRE),在JDK1.1.2中对调用API在几个方面作了扩展。这些变化没有破坏任何已有代码,JNI本地方法接口也没有改变。JDK1_1InitArgs结构中的reserved0域已被重新命名为version。JDK1_1InitArgs结构保存JNI_CreateJavaVM的初始化参数。JNI_GetDefaultJavaVMInitArgs和JNI_CreateJavaVM的调用者必须将版本域设置为0x00010001。JNI_GetDefaultJavaVMInitArgs被更改为返回
本文标题:15Java本地接口规范
链接地址:https://www.777doc.com/doc-4157586 .html