• 字节码指令和汇编指令的区别:

我们都知道java是一种跨平台的语言,那么java是如何实现这种平台无关性的呢?
这就需要我们了解JVM和java的字节码文件。这里我们需要有一点共识,就是任何一门编程语言都需要转换为与平台相关的汇编指令才能够最终被硬件执行,比如C和C++都将我们的源代码直接编译成与CPU相关的汇编指令给CPU执行。
不同系列的CPU的体系架构不同,所以它们的汇编指令也有不同,比如X86架构的CPU对应于X86汇编指令,arm架构的CPU对应于arm汇编指令。如果将程序源代码直接编译成与硬件相关的底层汇编指令,那么程序的跨平台性也就大打折扣,但执行性能相对较高。为了实现平台无关性,java的编译器javac并不是将java的源程序直接编译成与平台相关的汇编指令,而是编译成一种中间语言,即java的class字节码文件。字节码文件,顾名思义存的就是字节码,即一个一个的字节。有打开过java字节码文件研读过的小伙伴可能会发现,字节码文件里面存的并不是二进制,而是十六进制,这是因为二进制太长了,一个字节要由8位二进制组成。所以用十六进制标表示,两个十六进制就可以表示一个字节。java源码编译后的字节码文件是不能够直接被CPU执行的,那么该如何执行呢?答案是JVM,为了让java程序能够在不同的平台上执行,java官方提供了针对于各个平台的java虚拟机,JVM运行于硬件层之上,屏蔽各种平台的差异性。javac编译后的字节码文件统一由JVM来加载,最后再转化成与硬件相关的机器指令被CPU执行。知道了通过JVM来加载字节码文件,那么还有一个问题,就是JVM如何将字节码中的每个字节和我们写的java源代码相关联,也就是JVM如何知道我们写的java源代码对应于class文件中的哪段十六进制,这段十六进制是干什么的,执行了什么功能?并且一大堆的十六进制,我们也看不懂啊。所以这就需要定义一个JVM层面的规范,在JVM层面抽象出一些我们能够认识的指令助记符,这些指令助记符就是java的字节码指令。