很多人问我学习java该如何学,我个人认为,如果你想理解深刻,需要知道它的一些基本原理,本文我们主要阐述了三个可能困扰大部人人很多的问题:1)JDK、JRE、JVM到底什么区别?2)java编译流程是怎么样的,它的跨平台性到底如何理解?3)为什么java虚拟机不设计成,直接解释源代码到机器码,把中间的字节码省去?
1)JDK、JRE、JVM到底什么区别?
每一个初学者在用java编程开始之前,都会按网上的要求下载一个对应版本的JDK,但是有时候又有听人说需要另外再下载运行环境JRE,然后学着学着,又会听说JVM这个概念是各个大厂招收工程师所必须的知识点。那么这三个有什么区别呢?到底具备哪一个才可以运行java程序?
大家可以下载JDK安装包,并且可以打开它的目录结构,看看其中包含了什么:
![363f9f920ba6e3d6b00561d46e14f3af.png](https://i-blog.csdnimg.cn/blog_migrate/1b55445106b40ee06c0fbadd4a584aa6.jpeg)
1、JVM——java virtual machine,就是java虚拟机,所有的java程序会首先被编译为.class的类文件,通过jvm把class文件解释给本地操作系统cpu执行。所以java的跨平台性,通俗地讲就是我们字节码可以在任意装有jvm的操作系统上执行
2、JRE——java runtime environment,是指java运行环境。光有JVM还不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库。所以,在你写完java程序编译成.class之后,你可以把这个.class文件和jre一起打包发给朋友,这样你的朋友就可以运行你写程序了。(jre里有运行.class的java.exe)
3、JDK——java development kit,是java开发工具包,基本上每个学java的人都会先在机器上装一个JDK,那他都包含哪几部分呢?让我们看一下JDK的安装目录。在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的是以下四个文件夹:bin、include、lib、 jre。bin:最主要的是编译器(javac.exe),include:java和JVM交互用的头文,lib:类库。
2)java的编译解释流程是怎么样的,它的跨平台性如何理解?
在了解java的编译流程之前,我们先来看看普适性的高级语言是如何编译的
编译流程:
- 源码 [字符流]
- 词法分析 -> 单词(token)流
- 语法分析 -> 语法树 / 抽象语法树
- 语义分析 -> 标注了属性的抽象语法树
- 代码生成 -> 目标代码
- 操作系统/硬件 -> 执行结果
这里我们用c语言的编译来举例,c语言用gcc编译器进行编译的,其实就是把高级语言转化成机器码,然后底层的cpu和硬件就会按照机器码顺序执行指令,下图就是c编译的流程及常规输入输出的文件格式
![333b36a6959b45747bc68e347ef5f65c.png](https://i-blog.csdnimg.cn/blog_migrate/b8e554dec55f138928466530cc1ce448.jpeg)
java我们知道不同的是,它具有良好的跨平台性,“一次编译,到处运行”,这个我们经常在各个面试过程中被提起选择java作为企业级开发语言的原因。那么它的编译流程是怎么样的呢:
java编译流程:
- 源码 [字符流]
- 第1步:词法分析 -> 单词(token)流
- 第2步:语法分析 -> 语法树 / 抽象语法树
- 第3步:语义分析 -> 标注了属性的抽象语法树
- 第4步:代码生成 -> 字节码
- 第5步:代码生成 -> 机器码
- 第6步:操作系统/硬件 -> 执行结果
![c1689c89011e014632985114e1856222.png](https://i-blog.csdnimg.cn/blog_migrate/fa5cd2a887745de818494cbd45671492.jpeg)
从上面的图可以看到java源文件,首先是由javac编译器把源文件编译成class文件,也就是字节码的,然后通过jvm虚拟机把class文件转换成机器码进行执行。这下我们可以理解java的跨平台性了,他其实就用字节码作为中介码,然后用一个解释字节码的虚拟机来安装在不同的操作系统上面。这样各个操作系统都可以兼容地运行class文件,也就是可以远行java语言源文件。
3)想得多的同学会问,为什么java虚拟机不设计成,直接解释源代码到机器码,把中间的字节码省去?
从上面的java编译解释的流程来看。1-4步是javac编译器做的事情,第5步是jvm解释器做的事情,其实设计解释器有很多种方式,并不一定只限于做第5步,我们可以从后向前逐步把处理融合起来。每融合一个处理步骤,在“执行”之前的处理部分看起来就更少更简单了一些,但在“执行”时要做的冗余动作就更多了一些。
比如我们把4-5作为解释器也可以,也就是我们说的AST解释器。
只不过,目前的jvm这种方式在解释执行之前做好这些分析,就意味着在解释执行过程中完全不必关心这些检查,因而解释执行的效率就可以更高【是根据科学的统计效率得到的,也就是说这个方式是我们探索的最佳效率方案,所以同学们不必纠结啦】。
好了,至此我们把java基本的编译解释流程以及大家可能会疑惑的几个问题,通俗的阐述了一下,有需要讨论的可以直接私信我~~