Java是编译语言还是解释性编程语言?


169

过去,我使用C ++作为编程语言。我知道用C ++编写的代码会经过编译过程,直到成为目标代码“机器代码”为止。

我想知道Java在这方面如何工作。用户编写的Java代码如何由计算机运行?


14
可以解释C ++。有一些C解释器在那里。
汤姆·霍顿

Answers:


220

Java实现通常使用两步编译过程。Java编译器将Java源代码编译为字节码。字节码由Java虚拟机(JVM)执行。现代JVM使用称为即时(JIT)编译的技术将字节码编译为硬件CPU在运行时即时理解的本地指令。

JVM的某些实现可能选择解释字节码,而不是JIT将其编译为机器代码并直接运行。尽管它仍然被认为是“解释器”,但它与读取和执行高级源代码的解释器有很大不同(即,在这种情况下,不直接解释Java源代码,而对Java编译器的字节码进行直接解释。)

从技术上讲,可以提前将Java编译为本机代码并运行生成的二进制文件。也可以直接解释Java代码。

总而言之,根据执行环境的不同,字节码可以是:

  • 提前编译并作为本机代码执行(类似于大多数C ++编译器)
  • 及时编译并执行
  • 解释的
  • 由支持的处理器直接执行(字节码是某些CPU的本机指令集)

20
实际上,某些HotSpot JVM最初是通过解释字节码开始的,只有在弄清值得编译的内容并收集一些有关如何运行代码的统计信息之后,才将它们编译为本地代码。例如,找出在每个条件分支中采用的最常见路径。
Stephen C

1
因此,术语“热点” :)会根据经常运行的内容进行优化,以达到最佳效果。
中午丝绸

4
您可以使用-Xcomp在HotSpot中关闭解释器。值得尝试一个应用程序,看看它是一个坏主意。
汤姆·霍顿

1
有一条语句“当前的Sun HotSpot JVM版本使用一种称为即时(JIT)编译的技术,将字节码编译为CPU在运行时即时理解的本地指令。” 我给人的印象是JVM是解释器,但它建议它进一步编译字节码。我很困惑。也有记载说它是在运行时即时进行的。有人也可以解释吗?
Anand 2012年

由于Java是一种解释型语言,它将如何影响性能或任何Java应用程序执行
NAND

92

在此处输入图片说明

用Java编写的代码是:

  • 首先由一个称为javac的程序编译为字节码,如上图左部分所示;
  • 然后,如上图右部分所示,另一个名为java的程序启动Java运行时环境,它可以使用Java Interpreter / JIT编译器来编译和/或解释字节码。

Java何时解释字节码,何时编译字节码?最初解释了应用程序代码,但是JVM监视哪些字节码序列经常执行,并将其转换为机器码以直接在硬件上执行。对于仅执行几次的字节码,可以节省编译时间并减少初始延迟。对于频繁执行的字节码,在缓慢解释的初始阶段之后,将使用JIT编译来高速运行。此外,由于程序会花费大部分时间执行少量代码,因此减少的编译时间非常重要。最后,在初始代码解释期间,可以在编译之前收集执行统计信息,这有助于执行更好的优化。


是由于缓存的字节码导致Java使用了大量内存吗?
Pedro Gordo

3
@sedulam:“很多记忆”是一个模糊的陈述。Java的内存管理非常简单-JVM使用三代来创建和维护其对象。这另一SO答案可能是对您有用。
displayName

通过以上解释,从理论上讲,C ++编译的代码应始终比逻辑上相似的Java代码快,因为JIT决定始终将.class文件的某些部分决定不转换为机器代码。换句话说,Java永远无法赶上C ++展示的裸机执行速度。这是正确的假设吗?
DevdattaK

@DevdattaK:我对C ++不太了解,但是我猜想对于较小的专业程序,Java可能会更快地为您提供结果,因为它不会浪费时间来编译那些没有太多速度的代码部分。
displayName

1
@DevdattaK你的假设是在这个wiki页面讨论en.m.wikipedia.org/wiki/Java_performance?wprov=sfla1 总之,这并非总是如此。
Sundar Rajan '18

57

术语“解释语言”或“编译语言”没有意义,因为可以解释和/或编译任何编程语言。

对于Java的现有实现,大多数实现都涉及字节码的编译步骤,因此它们涉及编译。运行时还可以动态加载字节码,因此始终需要某种形式的字节码解释器。该解释器可能会也可能不会在内部使用对本机代码的编译。

如今,部分即时编译已用于许多曾经被视为“解释”的语言,例如JavaScript。


5
此外,Google的V8 JavaScript执行引擎不只是进行部分即时编译。它总是编译为本地代码,实际上,V8甚至没有解释器。它只有编译器(类似于Maxine,但与Maxine V8不同,它只有一个编译器)。所有这三个示例(GCJ,Maxine和V8)更能证明您的观点:没有诸如解释语言或编译语言之类的东西。语言不会被解释或编译。语言就是(这实际上是Shriram Krishnamurthi的引用)。
约尔格W¯¯米塔格

3
为什么在Java问题中谈论javascript?
Koray Tugay,2015年

1
@KorayTugay只是一个例子。我当然不想暗示Java和Javascript除了名称的前四个字母外,还有其他共同点。
starblue '17

解释语言和编译语言的区别至少不意味着编译语言二进制文件不能随时更改其执行流程,而解释语言对某些当前函数还是非常服从的?C语言的库是可选的,而在其他语言中,没有C语言二进制扩展名就不能拥有数组对象,而C语言二进制扩展名可以在另一个平台上更新或完全不同。脚本语言将能够同时在两种语言上运行,而编译后的语言将需要运行不同的二进制文件
Eaton Emmerich

53

Java被编译为字节码,然后字节码进入Java VM,后者对其进行解释。


33
...但并非严格准确。
Stephen C

2
JVM可能选择不“解释”字节码。它可以JIT编译并直接执行。
Mehrdad Afshari

1
JIT从技术上讲不是直接执行它。只是想起它是如何执行的。
cletus

Mehrdad:同意,我没有在这里描述可能的JIT操作,因为我认为这取决于JVM,而且我的回答还是很简单:)
Noon Silk

7
cletus:JIT 之后,它将直接执行。JIT正在读取一段字节码(例如,完整的方法),并编译为机器代码并跳转到机器代码。
Mehrdad Afshari

12

Java是一种编译的编程语言,但不是直接编译为可执行的机器代码,而是编译为称为JVM字节码的中间二进制格式。然后,编译并/或解释该字节码以运行该程序。


11

两者都有。首先,将Java编译(有些人希望说“翻译”)为字节码,然后根据JIT的心情对其进行编译或解释。


32
那是一种先进的软件,可以
激发

5
JIT确实是一个非常复杂的软件,它可以基于运行时信息(例如探查器)进行优化,而提前编译器则无法执行(因为它没有关于运行时信息的信息)。提前一个程序)。但这可能真的没有心情... :-)
杰斯珀(Jesper),2009年

5

Java同时进行编译和解释,

在Java中,程序不会编译为可执行文件。它们被编译成字节码(如前所述),然后JVM(Java虚拟机)在运行时解释/执行字节码。当我们使用javac编译器时,Java源代码被编译为字节码。字节码以文件扩展名.class保存在磁盘上

当程序要运行,字节码被转换的字节码可以被转换,使用刚刚在时间(JIT)编译器。结果是机器代码,然后将其馈送到内存并执行。

Javac是将Java代码编译为Bytecode 的Java编译器。JVM是Java虚拟机,它运行/解释/将字节码转换为本机代码。在Java中,尽管它被认为是一种解释语言,但当字节码位于JVM中时,它可能会使用JIT(即时)编译。JIT编译器读取很多部分(或很少见的完整部分)的字节码,并将它们动态地编译为机器代码,因此程序可以运行得更快,然后在以后进行缓存和重用而无需重新编译。因此,JIT编译将编译代码的速度与解释的灵活性结合在一起。

一个解释语言是一种类型的编程语言,其中大部分其实现方式的直接和自由地执行指令,而无需先前编译程序成机器语言指令。解释器直接执行程序,将每个语句转换为一个或多个已经编译为机器代码的子例程的序列。

编译语言是一种编程语言,其实现方式是通常的编译器(即从源代码生成机器代码转换器),而不是解释(步骤一步的源代码执行者,其中没有预运行时转换发生)

在像Java这样的现代编程语言实现中,提供这两种选择的平台越来越受欢迎。


应该是“字节码可以转换”,而不是“ 转换”。Java规范定义字节码。不管该字节码是(a)直接在硬件中运行,(b)通过解释器运行,(c)事先编译,还是(d)在运行时即时进行部分编译,都留作实现细节。请注意,所有这些选项确实确实已被各种实际的Java实现所使用。
罗勒·布尔克

感谢您指出了这一点。那么,如果字节码未转换为机器码怎么办?我可以想到一种方案,其中字节码是某些处理器的本机指令集,然后就不需要进行转换。还是我错过了什么。
总理

单击我为Jazelle DBX(直接字节码执行)技术提供的链接,其中JVM字节码的一个子集 CPU的本机机器指令(kinda-sorta)。否则,您会从字节码(a)从解释器(即时),(b)提前从编译器获得字节序生成机器代码,或(c)使用即时编译器在运行时即时生成机器代码(首先进行解释,然后有时在执行期间进行编译和缓存)。
罗勒·布尔克

-2

Java是针对基于Java的Java虚拟机平台的字节编译语言,该平台基于堆栈,并且在许多平台上都有非常快速的实现。


1
“字节编译”是什么意思?
杰斯珀,

2
@Jesper:“字节编译”通常表示“已编译为字节码”。“字节码”是一个通用术语,涵盖了任何类型的非文本中间代码(通常不可机执行)。
2009年

-3

引用来自:https : //blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

应用程序开发人员可以在当今市场上可用的各种OS上开发应用程序代码。在此阶段,Java语言与操作系统无关。由Java应用程序开发人员编写的出色的源代码现在被编译为Java字节码,在Java术语中称为客户端编译。这种对Java字节码的编译使Java开发人员能够“一次编写”。Java Byte代码可以在任何兼容的OS和服务器上运行,因此使源代码与OS / Server无关。创建Java字节代码后,Java应用程序与底层OS / Server之间的交互更加紧密。旅程继续进行-企业应用程序框架在称为Java虚拟机(JVM)或Java Runtime Environment(JRE)的运行时环境中执行这些Java Byte代码。JVM与底层操作系统和硬件紧密相连,因为它利用了操作系统和服务器提供的资源。现在,Java字节码已编译为特定于平台的机器语言可执行代码。这称为服务器端编译。

所以我想说Java绝对是一种编译语言。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.