Java是为网络而设计的。它具有平台无关性、安全性和网络移动性。从Java设计的初衷就考虑的这些问题,所以它具有一部分先天的优势。相对C/C++等早期高级语言而言。
Java体系结构包括四个独立但相关的技术:Java程序设计语言、Java Class文件格式、Java API、Java虚拟机。后两者组成了Java的一个平台,叫做Java运行时平台。我们平时说的Java 2平台就是指的这个。Java的可移植性,关键就在于它将平台相关的部分都集中到了Java运行时平台上,不同的操作平台有不同的Java运行时平台,而保证Java语言本身是标准统一的。
Java虚拟机规范并不规定具体的实现方式,它只是提出一种接口规范,勾勒出Java平台的特性。虚拟机的运行速度、方式和效率,和规范没有关系,跟具体的实现有很大的关系。比如虚拟机中的执行引擎,常见的是三种:一次性解释字节码、即时编译器(JIT)、自适应优化器。另外,对于特定的硬件,还有硬件实现的虚拟机。
Java虚拟机还有另外一种形式,那就是本地化方法(JNI)。本地化方法在Java标准之外又提供了对特定平台的特定功能或者效率方面的支持。在实现上,JNI在被调用之后,将从Java虚拟机手中接手所有的控制权,包括是否把控制权返回Java虚拟机;而在安全性方面,JNI也是没有保障的。所以可以认为JNI的地位实质上跟Java虚拟机是一样的。可以说,JNI就是Java虚拟机的扩展。这也是为什么Sun一直鼓励纯Java软件的开发的原因之一。
Java虚拟机的结构是由类装载器和执行引擎两部分组成的。而虚拟机的特性,也是由这两个部分一起来完成的。
类装载器是所有Java Class文件的装载入口,所以在控制安全性的流程中,它也仅排在Class文件后面。最底层的是“启动”(Bootstrap)类装载器,它是Java虚拟机实现的一部分。其次是系统类装载器,负责装载Java API的系统级类。最后是用户自定义的类装载器。如果一个对象被调用,那么它的默认类装载器将是它的调用者的类装载器。这样,它和它的调用者就通过类装载器动态的联系了起来。很著名的一个例子,就是Java Applet使用的类装载器,是通过网络来下载Class文件装载的。
Java class文件。这是一个有统一标准的二进制文件。和其他的Java特性一样,它的统一有赖于Java虚拟机将所有的不统一都揽在身上。可以说,Class文件的作用,就是方便快捷安全的在网络在不同的计算机间传递。Java号称的“一次编写,到处使用”,class文件起了很重要的作用。
Java API。这是Java提供给使用者的访问不同主机资源的统一方法。它一定是平台相关的,不同的平台会有不同的Java API实现。但是他们都遵循同样的API接口标准,保证了Java平台的平台无关性。除了具体实现,Java API的设计也煞费苦心,在接口一层尽量少的和平台相关,比如AWT和SWing的设计,就在追求一种平台的无关性,从设计到实现。另外一个例子,J2ME里面的GCF(通用连接框架)更是这种思路淋漓尽致的体现。所有的连接方式,都统一成为一个connect()函数和一个url地址。
Java编程语言。Java语言本身,是对过去面向过程/面向对象的编程语言的一次反省和总结。从新的起点出发,让Java不必受限于过去的历史,而成为一种全新的拥有当时最新最先进技术总结和经验总结的编程语言。.net固然强大,有MS的支撑,但是怎么看怎么像是MS高超的抄袭中的一件作品。现在Java平台日趋稳定,但是Java语言却一直在大步前进的改变着自己。
当然,我们在看到这些优点的同时,也必须看到Java提供的这些特性所固有的缺点,效率,兼容带来的不完美在Java一路上都被指指点点。我们无法改变这些Java本身的毛病,但是却要求我们在编写Java程序的时候,需要比其他语言的程序员更加兼顾效率和代码的优雅。这是一种压力,也是一种荣幸。
Java虚拟机的平台无关性。
首先,为什么要平台无关。这是很明显的,现在不管是计算机硬件还是操作系统软件,甚至于家用电器软硬件都是纷繁复杂,万千种类的了。
所以,一个统一的开发运行平台对于业界来说是极为重要的事情,庆幸的是,Java的设计初衷就是在家电等移动性嵌入式设备上发挥作用。所以说跨平台本来就是Java的基本职责。
Java体系结构对平台无关性的支持:
Java体系结构通过很多方面提供对平台无关性的支持。其中Java平台是最主要的方面。Java平台扮演了一个运行时Java程序与其下操作系统和硬件之间的缓冲角色。换个角度看,Java平台实际上充当了一个标准的OS,只是这个OS目前看起来还过于笨重:)
Java编程语言本身对平台无关性也提供了相应的支持,但是这是建立在Java平台的基础上的。对于C/C++程序员来说,最明显的一个例子就是对基本数据类型的值域和行为的定义上。以前我们一直强调不同的平台,不同的机器,不同的CPU都有不同的字节长度定义,但是在Java中,已经不存在这种差别了,因为Java语言统一了这些。至于究竟实际的硬件是怎么工作的,对于Java程序员来说,已经不用去关心了。Java平台已经自动的完成了这种转换。
另外一个对平台无关性提供支持的方面是Java的Class文件格式。它对于所有的Java虚拟机都是标准统一的,这也为跨平台传递程序代码提供了实现。
所以,总体上来看,Java体系结构对平台无关性的支持,主要来自于Java平台的设计,相当于为不同的硬件和操作系统提供了一层标准的外壳,Java体系结构将操作建立在一个虚拟的平台上,也就达到了平台无关的目的,虽然同时也带来了很多的缺点。但是这种趋势是不可阻挡的。
当然,说到平台无关性,不可忽略的是Java不仅在计算机领域实现了跨平台,而且在智能设备领域也实现了跨平台。这是通过定义不同的虚拟机标准来实现的。也就是我们耳熟能详的J2EE,J2SE,J2ME。实际上,这三个Java版本就是在不同的智能设备上的虚拟机规范。而在J2ME领域,平台无关性体现得就更明显了,因为移动/嵌入式设备的厂商和标准都比计算机领域多得多,统一的难度也就大得多了。所以在J2ME领域,除了有J2ME这个大框架,还针对各个更细小的领域定义了各自的虚拟机标准,这些标准被称作profile。
影响平台无关性的因素
虽然平台无关性看起来是那么的诱人,但是在编写Java程序的时候,平台无关性只是一个选项,并不是一个必选项。从根本上来说,任何Java程序的平台无关程度都依赖于作者怎么编写它。
首先影响的因素是Java平台的部署。Java平台的平台无关特性决定了要运行Java程序就必须要在客户机上安装符合客户操作系统的Java平台,也就是Java虚拟机。这并不是每一台计算机每一种操作系统都能满足的条件。但是幸运的是Java已经得到了广泛的推广,所以这个问题在大部分客户那里已经得到了解决。
第二个影响的因素是Java平台的版本。这个问题主要集中在Java不同版本的Java API上。虽然Java平台比较稳定,但是Java API的改动是比较频繁的,这种改动会导致新版本的Java程序不能在旧平台上运行,这也是开发语言的通病。
第三个因素是本地方法。当Java要用到一些操作系统平台的特性,需要使用本地方法的时候,就会破坏平台无关性。sun一直在大力推广纯Java程序,就是想通过程序员的努力,尽量避免使用本地方法。
第四个因素是非标准运行时库。虽然本地方法会破坏平台无关性,但是Java API提供的标准方法中使用的本地方法却不在其列。在标准API之外,还有一些厂商和组织提供的非标准方法,这些方法有可能使用了本地方法,却不是任何Java平台都拥有的,所以对于这种非标准方法,一定要谨慎使用,如果它们使用了本地方法来实现,那么平台无关性就被破坏了。
第五个因素是对虚拟机的依赖。在分析Java虚拟机的时候,需要牢记的一点是,虚拟机不过是Sun提供的一个文字标准,并不是具体的实现,我们平时用的虚拟机是Sun提供的,但是这并不是标准的虚拟机实现,实际上虚拟机并没有标准的实现,唯一的标准就是Sun给出的那份标准。所以对于虚拟机标准提供的一些特性,千万不能作为程序逻辑的一部分。因为标准只是指出一定要实现这些特性,但是具体怎么实现,是由具体的虚拟机实现决定的。一些可以举例的特性是垃圾回收机制,线程优先级等等。它们被实现了,但是并没有一个确定的实现方式,比如垃圾回收的时机,线程优先级高低是否一定决定了CPU时间分配的多少等等。
最后一个和平台无关性的因素是对用户界面的依赖。在不同的Java平台上,要保证每个平台的UI都让用户满意是很困难的事情。所以在跨平台设计的时候,要谨慎的设计UI的接口,以保证在每个平台上都有令人满意的表现。