【JVM】编译解释 可以把这部分理解成一句话Java 不是单纯的编译型语言也不是单纯的解释型语言而是“先编译再解释运行中再可能即时编译”的混合型语言。1. 什么是编译编译就是在程序运行之前先把源代码整体翻译成机器能直接执行的代码。比如 C 语言hello.c → 编译器编译 → hello.exe生成的hello.exe就是机器码文件操作系统可以直接运行。所以 C 语言通常叫编译型语言。特点是源代码 → 机器码 → 直接运行2. 什么是解释解释就是程序运行时解释器一边读代码一边翻译一边执行。比如 JavaScript、Python 的常见执行方式源代码 → 解释器逐行解释 → 执行它通常不会提前生成一个真正的机器码可执行文件。所以解释型语言的特点是边翻译边执行3. Java 为什么特殊Java 的执行过程不是简单的一步。它大概分成三步Java 源代码 ↓ javac 编译 字节码 .class 文件 ↓ JVM 解释执行 机器执行比如Hello.java先通过javac编译成Hello.class但是注意.class文件不是机器码而是字节码。机器不能直接执行字节码必须交给JVM。4. 字节码是什么字节码可以理解成一种中间代码。它既不是 Java 源代码也不是最终的机器码。Java 源代码人能看懂 字节码JVM 能看懂 机器码CPU 能看懂Java 这样设计是为了跨平台。比如同一份.class文件Windows 上的 JVM 可以执行 Linux 上的 JVM 可以执行 Mac 上的 JVM 也可以执行也就是常说的一次编译到处运行准确点说是一次编译成字节码只要有对应平台的 JVM就可以运行5. JVM 怎么执行字节码JVM 执行字节码主要有两种方式第一种解释执行JVM 的解释器一条一条读取字节码然后翻译成机器指令执行。类似字节码 → JVM解释器 → 机器码 → CPU执行这种方式启动快但是如果某段代码反复执行每次都解释就比较浪费。第二种JIT 即时编译JVM 在运行过程中会观察代码。如果发现某个方法或者循环执行得特别频繁就会认为它是热点代码。比如for(inti0;i1000000;i){sumi;}这种循环执行次数很多JVM 就可能觉得这段代码太常用了别每次解释了直接编译成机器码吧。于是 JIT 编译器会把这段热点字节码编译成机器码。之后再执行这段代码时就可以直接执行机器码了速度更快。流程是热点字节码 → JIT编译器 → 机器码 → 直接执行6. 所以 Java 到底是编译型还是解释型严格来说Java 同时包含编译和解释。因为它先有一次编译.java → .class这是编译。然后运行时 JVM 解释执行字节码.class → JVM解释执行这是解释。运行过程中热点代码还会被 JIT 编译成机器码热点字节码 → 机器码这又是编译。所以 Java 的完整过程可以理解为.java 源文件 ↓ javac 编译 .class 字节码 ↓ JVM 解释执行 机器执行 运行过程中 热点代码 ↓ JIT 即时编译 机器码 ↓ 直接执行7. AOT 又是什么AOT 是Ahead Of Time提前编译。它和 JIT 不一样。JIT 是运行时发现热点代码再编译成机器码AOT 是程序运行前就提前编译成机器码所以 AOT 更接近传统编译型语言。比如Java代码/字节码 → AOT编译 → 本地机器码这样程序启动可能更快因为不需要运行时再慢慢解释和 JIT 优化。8. 面试可以怎么说可以这样回答Java 不能简单地说是编译型语言或者解释型语言它是编译和解释并存的语言。Java 源代码会先通过 javac 编译成字节码文件也就是.class文件这一步属于编译。但字节码不是机器码不能被 CPU 直接执行需要交给 JVM 解释执行。在程序运行过程中如果 JVM 发现某些方法或代码块执行得很频繁就会通过 JIT 即时编译器把这些热点代码编译成本地机器码提高执行效率。所以 Java 是一种既有编译过程也有解释执行同时还支持 JIT 优化的语言。再简短一点Java 是半编译半解释型语言。先通过 javac 编译成字节码再由 JVM 解释执行运行过程中热点代码会被 JIT 编译成机器码直接执行所以 Java 既有编译也有解释。