Java体系结构包括四个独立但相关的技术:
- Java程序设计语言。
- Java class文件格式。
- Java应用编程接口(API)。
- Java虚拟机。
当编写并运行一个Java程序时,就同时体验了这四种技术。用Java编写语言编写源代码,把它编译成Java class文件,然后再在Java虚拟机中运行class文件。当编写程序时,通过调用类(这些类实现了Java API)中的方法来访问系统资源(如:I/O)。当程序运行的时候,它通过调用class文件中实现了Java API的方法来满足程序的Java API调用。如下图:
Java虚拟机和Java API一起组成了一个“平台”,所有java程序都在这个上面编译。java虚拟机和Java API的组合除了被称为java运行时系统之外,还称为Java平台。java程序可以在不同的计算机上运行,这是因为Java平台自己可以用软件实现。
一、java虚拟机
java虚拟机的主要任务是装载class文件并且执行其中的字节码,如下图可以看到,java虚拟机包含一个类装载器(class loader),它可以从程序和API中装载class文件。java API中只有程序执行时需要的那些类才会被装载。字节码由执行引擎来执行。
当Java虚拟机是由主机操作系统上的软件实现的时候,Java程序通过调用本地方法(native method)和主机交互。Java中有两种方法:Java方法和本地方法。Java方法是由Java语言编写的,编译成字节码,存储在class文件中的。本地方法是由其他语言(如C,C++或者汇编语言)编写的,编译成和处理器相关的机器代码。本地方法保持在动态链接库中,格式是各个平台专有的。Java方法是与平台无关的,但是本地方法是和平台密切相关的。运行中的Java程序调用本地方法时,虚拟机加载包含这个本地方法的动态库,并调用这个方法。在下图中可以看到,本地方法是联系Java程序和底层主机操作系统的连接方法。
二、类加载器的体系结构
一个Java应用程序可以使用两种类加载器:“启动”(bootstrap)和用户自定义类加载器。启动类加载器是Java虚拟机实现的一部分。启动类加载器通常使用某种默认方式从本地磁盘中加载类,包括Java API的类(启动类加载器也称为原始类加载器、系统类加载器或者默认类加载器)。java应用程序能够在运行时安装用户自定义的类加载器,这种类加载器能使用自定义的方式来加载类,用户自定义类加载器使用Java编写,能够被编译为class文件,能有被虚拟机加载,还能够像其他对象一样实例化,是运行中的java应用程序可执行代码的一部分。
由于有了用户自定义类加载器,所以不必再编译时就知道运行中的Java应用程序中最终会加入的所有的类,这样使得在运行时扩展Java应用程序称为可能。当它运行时,应用程序能够决定需要哪些额外的类,能够决定一个或者更多用户自定义的类加载器来加载。由于类加载器是使用java编写的,所以能用任何Java代码中可以表述的风格来进行类的加载。这些类可以通过网络下载,可以从数据库中获取,也可以动态生成。例如asm,cglib等都是动态生成字节码的库,aop、OSGI就是具体的使用。
三、Java class 文件
java class文件是可以允许在任何支持java虚拟机的硬件平台和操作系统上的二进制文件,所谓“一次编译,到处运行”,二进制文件扮演着重要角色。java编译后生成的class文件跟具体的硬件平台和操作系统无关,这样二进制文件就可以在支持java虚拟机的任何平台执行,来保证java程序跟平台无关性。
四、java API
Java API是运行库的集合,它提供一套访问主机系统资源的标准方法。编写Java程序时,任何时候都需要引用到java API class 文件;运行时,虚拟机加载程序class文件所使用的java API class文件;所有被加载的class文件(包括从应用程序中和从Java API 中提取的)和所有已加载的动态库(包含本地方法)共同组成了在java虚拟机上运行的整个程序。前面说过java程序的class 文件跟平台无关,而java API 的class文件跟平台密切相关,在一个平台能够支持Java程序以前,必须在这个特定的平台上明确地实现API的功能。为了访问主机上的本地资源,Java API调用了本地方法,这样java程序就不用再调用它们了。通过这种方法,Java API class文件为底层主机提供了具有平台无关性的、标准接口的java程序。对java程序而言,无论平台如何,Java API都会提供相同的表现和可预测的行为。正式由于在每个特定的平台上都明确地实现了Java虚拟机和Java API ,因此java程序本身就能够成为具有平台无关性的程序。如下图表示一个与平台无关性的程序。