
讲 Java 从编译到执行之前,先附上一幅图,能清晰的描述这一过程。
Java程序的执行过程
一个 Java 程序,首先经过 javac 编译成 class 文件,然后通过类加载器(ClassLoader)加载到 JVM,然后 JVM 将其加载到方法区,再通过执行引擎(比如字节码解释器)运行在操作系统(OS)上。执行时,JVM会调用操作系统相关的函数。
具体过程总结如下:
Java文件 -> 编译器(javac)-> 字节码 -> JVM -> 机器码
本地演示一下,Java 文件的执行过程。
第一步,准备一个可执行的 Java 文件,比如有一个HelloWorld.java 文件,代码如下:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
第二步,将 Java 文件编译成 class 文件,利用 javac 命令,格式:javac xxx.java,使用这个命令的前提是在系统环境变量里面,配置了 javac.exe 程序的路径,如下图:
确认命令可用之后,执行编译命令,
第三步,运行 .class 文件,利用 java 命令,格式: java xxx
JVM、JRE、JDK 的关系
从最上面的那张 Java 程序执行过程图,我们可以看到,一个Java程序的执行,JVM、JRE 和 JDK 都提供了一定的支持。
首先 JDK (Java Development Kit)是 Java 开发工具包,是一个大合集,是程序员开发的基础,里面提供了好多工具,比如 javac 可以把 Java 文件编译成 class 文件,java 可以执行 class 文件,jar 可以对 Java 项目进行打包,javap 可以用于反编译(反汇编)等。
我们安装 JDK 的时候,会发现 JDK 文件夹内部都会有一个 JRE 文件夹,JRE (Java Runtime Environment)是 Java 运行时环境,里面提供了很多的类库(就是 jar 包,它提供了一些即插即用的功能,比如说读取或操作文件、连接网络、文件 I/O 等)。
同时 JRE 里面还包含了特别重要的 JVM (Java Virtual Machine),JDK 提供了把 Java 文件编译成 class 文件的工具,JRE 提供了 Java 程序运行时需要的 Java 类库,而 JVM 则是负责把 class 文件解释成机器可以识别的机器码,再通过执行引擎运行在操作系统中。
JVM 的作用:从软件层面屏蔽不同操作系统在底层硬件和指令的不用。这是在宏观方面对 JVM 的方式。
同时 JVM 是一个虚拟化的操作系统,类似于 Linux 或者 Windows 的操作系统,只是它架在操作系统上,接收字节码也就是 class 文件,把字节码解释成操作系统上的机器码且进行执行。
JVM 的特性
跨平台性
我们平时写的 Java 类,可以在不同的操作系统(Linux、Windows、MacOS等平台)上执行,这就是 JVM 的跨平台性。为了实现跨平台性,不同操作系统有对应的 JDK 版本。
JDK 官网地址
跨语言性(语言无关性)
JVM 只识别字节码,和语言没有直接关联,所以 JVM 跟语言之间是解耦的。JVM 运行 Java 程序不是翻译 Java 文件,而是识别 class 文件,也就是字节码。像 Groovy、Kotlin、Scala 等语言,它们其实也是编译成字节码,所以它们也可以在 JVM 上执行,这个就是 JVM 的跨语言性(或者是语言无关性)。Java 的跨语言性一定程度上奠定了非常强大的 Java 语言生态圈。
总结
以上就是 Java 文件从编译到执行的过程的讲述,具体过程为:Java文件 -> 编译器(javac)-> 字节码 -> JVM -> 机器码。
其实上述过程中有两个很重要的步骤没有提到,就是类加载器把字节码文件加载到 JVM 中的过程和 JVM 把字节码解释成机器码的过程。这个重要且复杂的过程,下一篇文章再研究。
若有不对之处,敬请指正!