Java本身是一种面向对象的语言,最显著的特性有两个方面,一是所谓的“书写一次,到处运行(Write once,run anywhere)”,能够非常容易的获得跨平台能力;另外就是垃圾收集(GC,Garbage Collection),Java通过垃圾收集器回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。
JRE也就是Java的运行环境,包含了JVM和Java类库,以及一些模块等。而JDK是Java的开发工具,可以看成是JRE的一个超集,提供了更多的工具,比如编译器、各种诊断工具等。也即JDK=JVM+Java类库+开发工具。其实很多 Java 程序员在写了很多代码后,你问他 jre 和 jdk 之间有什么关系,jvm 又是什么东西,很多人不知所云。本篇不会讲述 jvm 底层是如何与不同的系统进行交互的,而主要理清楚三者之间的区别,搞清楚我们写的 xxx.java 文件是被谁编译,又被谁执行,为什么能够跨平台运行。
首先,我们分别对这三者进行阐述。
JVM :英文名称(Java VirtualMachine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。
JRE :英文名称(Java RuntimeEnvironment),我们叫它:Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。
JDK :英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。
显然,这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM。
JRE也就是Java的运行环境,包含了JVM和Java类库,以及一些模块等。而JDK是Java的开发工具,可以看成是JRE的一个超集,提供了更多的工具,比如编译器、各种诊断工具等。也即JDK=JVM+Java类库+开发工具。
Java 为什么能跨平台,实现一次编写,多处运行?
Java 能够跨平台运行的核心在于 JVM 。不是 Java 能够跨平台,而是它的 jvm 能够跨平台。我们知道,不同的操作系统向上的 API 肯定是不同的,那么如果我们想要写一段代码调用系统的声音设备,就需要针对不同系统的 API 写出不同的代码来完成动作。
而 Java 引入了字节码的概念,jvm 只能认识字节码,并将它们解释到系统的 API 调用。针对不同的系统有不同的 jvm 实现,有 Linux 版本的 jvm 实现,也有 Windows 版本的 jvm 实现,但是同一段代码在编译后的字节码是一样的。引用上面的例子,在 Java API 层面,我们调用系统声音设备的代码是唯一的,和系统无关,编译生成的字节码也是唯一的。但是同一段字节码,在不同的 jvm 实现上会映射到不同系统的 API 调用,从而实现代码的不加修改即可跨平台运行。
对于“Java是解释执行”这句话,这个说法是不太准确的。我们开发的Java源代码,首先通过Javac编译成为字节码,然后在运行时,通过Java虚拟机JVM内嵌的解释器将字节码转换成为最终的机器码。
对于Java平台的理解,可以从很多方面简明扼要的谈一下,例如:1)Java语言特性,包括面向对象、反射、泛型、Lambda等语言特性;2)基础类库,包括集合、IO/NIO、网络、并发、安全等基础类库;3)或者谈谈JVM的一些基础概念和机制,比如Java类的加载机制,常用版本JDK(如JDK8)内嵌的ClassLoader,例如Bootstrap、Application和Extension ClassLoader;类加载大致过程:加载、验证、链接、初始化;自定义的ClassLoader等。还有垃圾收集的基本原理,最常见的垃圾收集器等。4)还有JDK包含的工具,如编译器、运行时环境、安全工具、诊断和监控工具等。
解释执行和编译执行
更详细内容参加八、JVM
参考书目:《深入理解JVM虚拟机》