“一次编译,到处执行” 又能体现 Java 的哪些思想?

分析

这是一个比较笼统的问题,可以从很多方面进行回答。Java 作为一种面向对象的语言,一方面是具有 “一次编译,到处执行” 的跨平台能力,另一方面是具有垃圾回收机制,利用垃圾收集器回收内存,不用向 C++ 那样考虑 那么多 的内存分配问题。

“Java 是解释执行” 这句话如果细说的话,可以认为首先将 Java 源代码 编译为 字节码,然后在运行时,通过 Java 虚拟机内嵌的解释器(Interpreter)将 字节码 转换成最终计算机能够识别的 机器码,从而让机器能够执行。但像 HotSpot 这样的虚拟机,为了 Java 程序执行的高效,还提供了一种 JIT(Just In Time Compiler) 编译器,即 动态编译 或 即时编译。该方式能够使得程序在 运行时热点代码(Hot Spot Code) 编译成与平台相关的 机器码,并进行各种层次的优化。这种情况下,对于部分 热点代码 来说就属于 编译执行 而不是 解释执行

所谓的 热点代码 就是说:当虚拟机通过解释器执行字节码文件的时候,当虚拟机发现某个方法或者代码块的运行特别繁琐的时候,就会把这部分代码称为 热点代码

对于 “如何理解 Java?”,涉及了许多方面,如下所示:

  • 基本语言特性、面向对象、反射、泛型等;
  • Java 类库
    • 核心类库,如 IO/NIO、网络、工具类等;
    • 安全类库;
    • JDK Management 类库;
    • 第三方类库;
  • Java 虚拟机
    • GC;
    • 运行时;
    • 动态编译;
    • 辅助功能,如 JFR 等;
  • 工具
    • 辅助工具,如 JLink、JAR、JDeps 等;
    • 编译器,如 javac、sjavac;
    • 诊断工具,如 jmap、jstack、jconsole、jhsdb、jcmd 等。

我觉得对于这种范围涉及的比较广的问题,最好能把实现原理弄清楚。对于 “一次编译,到处执行” 说的是 Java 语言跨平台的特性,这种特性和 Java 虚拟机有关,由于不同平台下都含有对应的 JDK,这就为 Java 语言的运行提供了必要的环境。这里并不是说 Java 语言可以实现跨平台,只不过是说在不同的平台下都有可以让 Java 语言运行的环境而已,所以就有了一次编译,到处运行的效果。

Java 分为 编译期运行时,执行流程为 编码->编译->运行

对于 编译期 来说,是将 Java 源代码编译成 .class 文件,即 字节码 文件,这种文件就是可以到处运行的文件,这一步完成了第一次编译;然后 Java 字节码文件会被 JVM 编译为目标机器代码,这是 Java 的第二次编译。

对于 运行时 来说,“到处运行” 需要的是 JVM,在任何可以运行 Java 程序的地方都含有一个 JVM 操作系统,因此实现了到处运行的效果。此外,在 JDK 9 中,引入了一种新的编译方式,即 AOT(Ahead of Time Compliation),该方式可以将字节码编译成机器码。当然,这是围绕着虚拟机的效率问题进行展开的一些优化技术。

参考