Java技术在网络环境下非常有用,其中一个关键理由是,用Java创建的可执行二进制程序,能够不加改变地运行于多个平台。
这样的平台无关性随之带来许多的好处。这将极大地减轻系统管理员的工作;此外Java的平台无关性在嵌入式设备环境下也非常有用;从开发者的观点看,Java能够减少开发和在多个平台上部署应用程序的成本和时间。
Java的平台无关性自然不言而喻。对于我们开发者来说,可能对下面的Java是如何实现支持平台无关的方法或原理更加感兴趣。
Java对平台无关性的支持,就像对安全性和网络移动性的支持一样,是分布在整个Java体系结构中的,所有的组成部分——语言、class文件、API以及虚拟机,都在对平台无关性的支持扮演着重要角色。
2.1、Java平台
Java平台扮演一个运行时Java程序与其下的硬件和操作系统之间的缓冲角色。Java程序被编译为可运行于Java虚拟机中的二进制程序,并且假定Java API的class文件在运行时是可用的。接着虚拟机运行程序,那些API则给予程序访问底层计算机资源的能力。无论Java程序被部署到何处,它只需要与Java平台交互,而不需要担心底层的硬件和操作系统。
2.2、Java语言
Java编程语言主要通过以下方式支持Java的平台无关性:它的基本数据类型的值域和行为都是由语言自己定义的。
在像C/C++这样的语言中,基本数据类型int的值域是由它的占位宽度决定的,而它的占位宽度则由平台决定的。而Java程序,不管其运行的平台是什么,Java中的int都是32位二进制不骂表示的有符号整数,而float则总是遵循IEEE754浮点标准的32位浮点数。同样,这一点在Java虚拟机内部以及class文件中都是一致的。通过确保基本数据类型在所有平台上的一致性,Java语言本身为Java程序的无平台性提供了强有力的支持。
2.3、Java class文件
Java class文件可以在任何平台上创建,也可以被任何平台的Java虚拟机装入并运行。它的格式,包括多字节值的高位优先存放约定,都有严格定义,并且是与Java虚拟机所在平台无关。
2.4、可伸缩性
Java支持平台无关,一个方面就是它的可伸缩性。Java平台可以在各种各样不同类型(从嵌入式设备到大型主机)的计算机上实现。
Sun改变过的API定义方式得到了三个基本API集合,它们表现Java平台的不同的伸缩性:
(1)企业版(J2EE),Java网路编程 主要用来写一些动态网站
(2)标准版(J2SE),Core Java 简称java核心基础 主要用来写一些C/S架构的程序
(3)微型版(J2ME),Java移动开发 主要用来开发java手机应用
当编写Java程序时,平台无关性只是一个可选的性能。Java程序的平台无关程度依赖于多种因素,其中有些因素不在开发人员的控制范围内,但大多数是由开发人员控制的。从根本上说,任何Java程序的平也台无关程度都依赖于作者怎么编写它。
平也台无关程度影响因素有如下几点:
3.1、Java平台的部署
只有拥有Java平台的计算机或设备才能运行Java程序。设备运行Java程序前,需要做两件事,首先必须将Java平台移植到对应设备上,此外,实现接口还必须安装到对应设备上。
3.2、Java平台的版本
并非所有的标准运行时库在每个Java平台上都是可用的。作为一名开发人员,你不可能控制Java版本的发布周期或者部署进度,但是你可以选择自己的程序所依赖的Java平台。
3.3、本地方法
决定Java程序的平台无关程度的另一个主要因素就是你是否调用了本地方法。编写Java程序时,必须遵守的一条最重要的原则就是:不要直接或间接调用不属于Java API的本地方法。如果必须使用本地方法,而且要使程序可以在多种平台上运行,必须将本地方法移植到所有需要的平台上。
3.4、非标准运行库
Java平台可以由许多开发商来实现,虽然每个开发商必须提供Java API的标准运行时库,但是个别开发商还可能提供了另外的库。如果开发者侧重于平台无关性,那么就必须清楚地知道所使用的那些非标准运行时库是否调用了本地方法。如没有调用本地方法的非标准库不会降低程序的平台无关性。否则,会事程序和平台相关了。
3.5、对虚拟机的依赖
在编写平台独立的Java程序时,还必须遵从两条原则,这两条原则和Java虚拟机中的某些部分有关,Java虚拟机中的某些部分可以由不同的开发商用不同的方法实现。这两条原则是:
1)不要依赖及时终结(finalization)来达到程序的正确性;
2)不要依赖线程的优先级(thread prioritization)来达到程序的正确性。
这两条原则可以防止Java虚拟机规范中运行的垃圾收集和线程在不同的实现中的变化带来的不利影响。
所有的Java虚拟机都必须有垃圾收集堆,但是不同的实现可能使用不同的垃圾收集技术。在Java虚拟机规范中的这个灵活性意味着,在不同的虚拟机中,一个特定的Java程序中的对象可能在不同的时间被垃圾收集。这也意味着那些在对象被释放前由垃圾收集器运行的终结方法(finalizer),在不同的虚拟机这可能是不同的时间运行的。如果使用了一个终结方法来释放有限的内存资源,例如文件句柄,程序就可能可以在一些虚拟机的实现上运行,而在其它实现上却不能。在一些实现上,程序可能在垃圾收集器得到机会调用释放资源的终结方法之前,就已经将有限的资源耗尽了。
在不同的Java虚拟机的实现中,另一个变化和线程的优先级有关。Java虚拟机规范只保证了,程序中所有拥有最高优先级的可运行线程将会得到一些CPU时间。这个规范也保证了在较高优先级的线程被阻塞时,较低优先级的线程将会运行。但是,在较高优先级的线程没有被阻塞的情况下,并没有禁止较低优先级的线程的运行。在某些虚拟机的实现中,即使较高优先级的线程并未被阻塞,那些较低优先级的线程也可能先得到CPU时间。如果你的程序依赖于这个行为的正确性,它将在某些虚拟机的实现上可以正常运行,而在某些实现上却不能。为了保证多线程Java程序的平台独立,必须依赖同步(sychronization)而不是优先级来在线程之间协调相互间的动作。
3.6、对用户界面的依赖
在不同的Java平台的实现之间 ,另一个主要的变化就是用户的接口:在编写平台独立的Java程序时,用户界面是一个更为困难的问题。用户必须利用这些基础类库建立一个接口,使许多不同平台上的用户使用起来比较舒适,这往往不是一项简单的工作。
虽然AWT和Swing库使得创建运行在不同平台上的用户界面变得比较容易,但是它们并不一定使界面设计变得方便、界面必须使不同平台上的用户使用起来感觉到愉快。
3.7、Java平台实现中的bug
Java平台的不同实现之间还有一个变化就是bug,虽然Sun已经开发了一套全面的测试标准,Java平台实现必须通过这套标准测试。但是可能某些实现在发布的时候仍然包含bug。你只能通过测试来防止这种可能性。如果确实影响,那么就必须试图找到一个绕开的途径。
3.8、测试
因为Java平台的实现之间可能存在差异,依赖某些特定平台写的Java程序,已经在任何特定平台的实现中可能存在的bug。所以应该尽可能在所有希望运行的平台上对Java程序进行测试。在实际情况中,在程序要运行的不同主机和不同Java平台实现上测试你的Java程序,是程序平台无关性的一个关键因素。
除了上面的内容外,《深入Java虚拟机 第二版》中,关于平台无关内容还有:平台无关的七个步骤、平台无关性的策略、平台无关性和网络移动对象
对于博主目前而言,了解Java如何实现平台无关的支持和影响平台无关性的因素的内容就足够了。如果需要猿友们可以下载《深入Java虚拟机 第二版》自行学习了解。
参考书籍:《深入Java虚拟机 第二版》