我读到过,Java源代码被编译成“字节码”,然后通过JIT再次编译成“机器码”。也就是说,源代码首先被编译成平台无关的字节码,然后再次编译成特定于机器的代码。那么为什么Java被称为既是解释型语言又是编译型语言呢?解释是在哪里进行的?
我读到过,Java源代码被编译成“字节码”,然后通过JIT再次编译成“机器码”。也就是说,源代码首先被编译成平台无关的字节码,然后再次编译成特定于机器的代码。那么为什么Java被称为既是解释型语言又是编译型语言呢?解释是在哪里进行的?
这里有一些误解。
在正常情况下,Java编译器(javac
)将Java代码编译成字节码,然后Java解释器(java
)逐行解释这些字节码,将其转换为机器语言并执行。
JIT(即时)
编译器是一个稍微不同的概念。JVM维护一个函数被执行的次数计数。如果超过限制,则启用JIT。Java代码直接编译成机器语言,然后用于执行该函数。
它有一个规范(JLS),定义了Java程序应该如何运行。
作为一种语言本身,它并没有指定它在不同平台上应该如何执行。它的运行方式,使用JIT还是不使用JIT,完全基于实现。
如果我明天编写一个Java运行时,根本不进行JIT编译,我可以称之为Java解释器。
如果我采用一个将Java字节码作为汇编代码的Java虚拟机(人们真的做过这样的事情),我可以称之为Java严格编译。
很多其他语言也是这样:
Java是混合语言,即它既是编译型(前期工作)又是解释型(接收端工作)。
字节码是Java的中间语言。Java源代码通过javac
编译为字节码。有时,这些字节码再次编译成机器语言,这被称为JIT(即时编译)编译。
JIT编译是执行计算机代码的一种方式,它涉及在程序执行期间-运行时-对代码进行编译,而不是在执行之前。 来源
JVM(没有JIT)将Java中间语言字节码解释为本地机器语言,具体如下:
JVM是一个抽象计算机,它有多个实现:
HotSpot(解释器 + JIT编译器):主要参考Java VM实现。被Oracle Java和OpenJDK使用。
JamVM(解释器):设计成与其他虚拟机相比非常小。旨在使用GNU Classpath。支持多个架构。GPL许可证。
ART(解释器 + AOT编译器,即提前编译):Android运行时是Android操作系统中使用的应用程序运行环境,取代了Dalvik(解释器+JIT编译器)。
javac是一个编译器,它将Java代码转换为字节码(参见字节码),如果我们有JVM(Java虚拟机),则可以在任何计算机上轻松运行。解释器将Java字节码转换为机器码。
与其他编程语言不同,Java是一种编译和解释的语言。Java IDE充当编译器,而JVM(Java虚拟机)则像解释器一样运行。也就是说,当任何程序(比如Hello)被保存为Hello.java并编译后,我们会得到一个扩展名为Hello.Class的文件,称为类文件、字节码或中间代码。字节码不依赖于任何特定的机器,因此也被称为中间代码。 为了将这个字节码转换成机器码或机器可理解的格式,需要使用不同操作系统的JVM。JIT(即时编译器)是JVM的一部分,默认情况下启用,可以在“即时”编译字节码为本地机器码。
它有两个目的。第一个是确保代码在语法和语义上是正确的。其次,编译过程会产生字节码。正如您所指出的,这是一种与体系结构无关的中间语言,可以由JVM解释或即时编译为特定机器体系结构的本地代码。通过编译成字节码,许多与编译相关的开销可以提前完成,使得JVM能够从已经经过彻底检查和严格验证的字节码生成本地代码或解释字节码。