想要学好Java编程,就必须先弄清楚Java程序是如何执行的。首先来解释一个最基本的概念:什么是程序?把你想让计算机做的事情用编程语言一条条列出,这个由多条编程语言所组成的“代码序列”就是程序。

那么Java程序又是如何运行的呢?这个过程如图1-1所示。

第一章《初学者问题大集合》第4节:Java程序是如何执行的?_字节码

图1-1 Java程序运行基本过程

开发者首先在纯文本编辑工具中写好一段Java程序,并把程序保存到一个文件当中,这段Java程序称为“源代码”,而保存源代码的文件称之为“源程序文件”,简称“源文件”。源文件的后缀名是“.java”。源文件的本质其实只是一个文本文档,类似于用记事本写的txt文件,它并不能执行。想要执行程序,还必须把Java程序编译成“字节码文件”。字节码文件的后缀名是“.class”,它也不是一个可以执行的文件,因为字节码文件中的代码并不是计算机能够识别的机器指令。

如果想要执行Java程序,还需要“Java虚拟机”的帮助。Java虚拟机把字节码文件中的代码读入到它的内存空间,这个过程称之为“加载”。加载过程完成之后,接下来Java虚拟机把字节码文件中的每一条代码都进行分析,解释成计算机能够识别的机器指令,然后把这些机器指令传达给计算机,最终由计算机来执行这些机器指令,这就是Java程序从编写到执行的基本过程。

这个过程并不复杂,但初学Java的读者对这个过程中很多细节和概念并不理解。比如:把源文件“编译”成字节码文件是个什么操作?是谁来完成编译操作的?为什么不直接把源程序编译成计算机可执行的文件呢?那个帮助我们执行Java程序的“Java虚拟机”又是个什么东西?下面就来一一解答这些问题。

把源文件转化为成字节码文件的过程称为“编译”,这个操作是一个叫做“编译器”的程序来完成的。其实,字节码文件中的内容仍然是开发者编写的Java程序,只不过它由原来程序员能直接阅读的文档形式(即Java源程序)变成了Java虚拟机才能读懂的字节码形式。

那么,为什么不直接把源代码编译成计算机可执行的机器指令呢?或者更直白的说:为什么不把Java源程序编译成一个计算机可以直接运行exe文件呢?因为exe文件其实就是由多条机器指令所组成文件,但不同机型、不同操作系统的计算机的机器指令系统并不完全相同。这就导致一个exe文件虽然能在A型计算机上直接运行,但它放在B型计算机上并不能运行。如果想让这段程序也能在B型计算机上运行,必须按照B型计算机的指令系统重新对程序进行编译。这就好比是有两个厨师,一个厨师是中国人,他不懂英文,而另一个厨师是英国人,他不懂中文。现在有一本中文版的菜谱,中国厨师可以直接按照菜谱做出菜肴,但英国厨师看着这本菜谱却什么也做不出来,因为他压根看不懂菜谱的内容。在这个对比中:中国厨师就如同A型计算机,英国厨师就如同B型计算机,他们能看懂的语言文字并不相同,而那本中文菜谱就如同一个只能运行在A型计算机上exe文件。早于Java诞生的C语言、C++等编程语言,都是把程序直接编译成exe文件的。这就导致这些语言编写的程序如果要在不同机型的计算机上运行,必须根据计算机的种类编译出多个版本的exe文件。

Java语言的创作者,是一位名叫James Gosling的软件开发大师,行业中很多从业者尊称他为“高司令”。高司令和他的团队在创造Java语言的时候,希望Java语言所编写的程序只要编译一次就能在各种不同的计算机上运行。但怎样才能解决exe文件无法兼容不同类型计算机的问题呢?高司令他们想到了用“Java虚拟机”来解决这个问题。

Java虚拟机,顾名思义,它并不是一种真实的计算机,而是由软件模拟出来的计算机。它在业界往往直接被简称为“虚拟机”,它的英文名为“Java Virtual Machine”,取其三个单词的首字母就是“JVM”,所以今后各位读者看到“JVM”这三个字母就应该知道它表示Java虚拟机。

那么,虚拟机为什么能让Java程序只编译一次就能在不同的机型上运行呢?基本思路是只需要两步:第一步,让Java语言所写代码一律不生成exe文件,而是生成一个只有虚拟机能读懂的“字节码文件”。 第二步,把字节码文件交给虚拟机,由虚拟机根据当前计算机机型,把字节码文件中的内容翻译成对应的机器指令,然后交给计算机执行。这样,有了虚拟机的帮助,就能做到:只编译一次源代码,却可以在不同类型计算机上运行Java程序。这个原理就好比是:有一本菜谱,中英两国的厨师都看不懂其中的内容,但是有一个精通多国语言的全能翻译能看懂菜谱。如果由中国厨师掌勺做饭,就把菜谱翻译成中文。同样,如果由英国厨师掌勺做饭,就把菜谱翻译成英文。这样,在全能翻译的帮助下,两位厨师都能按照菜谱做出同样的菜肴。在这个对比中,中英两国厨师仍然对应A、B两种不同的计算机,字节码文件就是那本两个厨师都看不懂的菜谱,而虚拟机就是那个全能翻译,中英两国厨师能按菜谱做出菜肴,都离不开全能翻译的帮助。这就是为什么Java程序运行需要一个虚拟机的原因。

高司令和他的团队把Java语言的这种“只编译一次源代码就能在各种不同类型计算机上运行程序”的特性称之为“一次编译,到处运行”,还有一种更精辟的概括叫做“跨平台”。因为有了跨平台这个特性:之前看到图1-1就可以重新被绘制为图1-2的形式:

第一章《初学者问题大集合》第4节:Java程序是如何执行的?_字节码_02

图1-2 Java语言跨平台实现原理

在重新绘制的示意图中可以看到,有了虚拟机的帮助,Java程序只需要编译一次,就能在Linux、windows、Mac以及其他各种操作系统多种平台上运行。

除此文字版教程外,小伙伴们还可以点击这里观看我在本站的视频课程学习Java。