学习java的过程中,我们一开始接触到就是如何运行一段java程序,那么java到底是如何编译和运行一段Java程序的呢,下面我来谈谈自己对这个问题的理解,同时也是对自己学习历程的回顾。
一、java语言的特点
我们一开始接触j一些java书籍时,可能开篇就谈及java的优越性以及它和其它语言的不同,其中最常被提及的可能就是java的可移植性和解释性语言。那么java的可移植性性是怎么来的呢,而这就涉及到java的编译过程。我们都知道,计算机只能识别二进制代码,也就是机器语言,类似java这样的编程语言叫做高级语言,但是计算机是不能识别高级语言的,高级语言本质是是为了方便人类编程而创造的,机器想要理解这种语言就必须把其翻译机器语言。而这种翻译的实现方法就诞生了两种类型的高级语言——即编译型和前面提到的解释型语言。而这两种语言是如何翻译高级语言的呢?打个比方,如果你要读一本外语书,你可以自己逐行翻译慢慢看完,但下一次你再读这本书你还是得翻译它,除此你也可以自己做一本译本,先全部翻译一遍然后一次性把它读完。而前一种方式就是解释型语言翻译的特点,我们读一次翻译一次,类比到程序上就是java程序运行一次就翻译一次,而后一种就像你第一遍读时直接把这本书翻译完成,后续就不用再翻译了,相比前者来说这种方式开始虽然辛苦,但从长远来说,后一种方式的阅读速度是要快于第一种的,而这也就是编译型语言的特点。
二、Java程序编译的过程
前面讲了结识型语言与编译型语言的差别,理解这种差别对我们接下来理解java程序的编译过程十分重要。首先java其实是一门半编译半解释型语言,我们书写完代码后,源代码会被保存为一个.java文件,当我们运行程序时,这个.java文件就会被java虚拟机(jvm)编译成一个.class(字节码)文件,而这种编译是一次性的,也就是说jvm对于把.java文件转为.class文件这件事只做一次,后续就不会再做了,当你第二次运行java程序时,jvm会去直接执行.class文件,而不会再去管先前的.java文件,而这种方式正是编译型语言的特点。那么jvm把.java文件转换为.class文件之后,整个翻译工作就结束了吗?当然没有,计算机同样不可以理解.class文件,jvm还是得把.class文件翻译为机器语言,不过这种翻译不再像前面那样直接一次翻译完,然后保存为一个相当于译本的文件,一劳永逸了,而是运行一次翻译一次,而这就体现了java解释性语言的特点了。
三、java为什么不直接把源代码翻译为机器语言?而是多次一举中间加了个字节码文件呢?
其实这个字节码文件正是java实现可移植性的奥秘。举个例子,我们今天出国旅行,要学一门外语与当地人沟通时,大多数人肯定选择英语,因为英语的传播范围最广。而java和机器语言的关系就像一个中国人和许多不同国家的外国人交流,这个中国人需要了解所有国家的语言才能跟所有外国人完成交流,但这个中国人只会英文,而这无疑是十分烦人的。而现在,走来了一个来自英国的语言学家,他对中国人说,你把你的话翻译成英文给我听,与其他人的交流让我来做,这个中国人当然乐意,因为现在他只用把中文翻译成英语就可以完成与所有人的交流,而以后不管他去哪个国家旅行,只要带上这个英国人,他就只要把自己的话翻译成英文给这个英国人听,就可以借他之口完成与当地人的交流。而.class文件在这个故事种就扮演着英国人的角色,负责把.java文件翻译给不同计算机系统理解。而实现这种翻译的正是java虚拟机,就像中国人带着那个英国人到处旅行一样,java也把自己的虚拟机和源程序一起带入各个系统,从而完成java程序在不同计算机系统上的运行。当然,就像那个英国人不可能会世界上所有国家的语言一样,java虚拟机也不可能去兼容所有系统,所有目前java虚拟机只兼容了目前比较流行的几个系统,例如window,linux。其实到这我们也可以看出,所谓的可移植,其实也是在大量的翻译工作和兼容系统的基础上的,java能做到这个还是因为它的使用者众多,成为了了行业巨头,才有机会去推行这种标准化。