在Java中,源代码编译成字节码的过程发生在哪里?

5

我搜索了一些内容,试图理解java源文件是如何执行的。我没有找到清晰的答案来说明从JRE和JDK术语开始到结束的步骤。因此,我正在写出我从不同博客中理解到的内容,但仍存在一些空白。对我的理解进行纠正是非常欢迎的。问题一和问题二标记为Q1和Q2,在第二点下面。

  1. 编写一个HelloWorld.java文件

  2. javac HelloWowrld.java会生成HelloWorld.class。这个class文件就是字节码。现在,我可以把在Mac上生成的这个字节码带到Windows机器上运行,应该可以正常工作。
    Q1:现在这个编译成字节码,这是真正的编译还是解释?
    Q2:javac必须是JDK的一部分而不是JRE?

  3. JRE包含JVM和其他库以创建运行时环境。JVM(本身是平台相关的)执行字节码到机器码。实际上是JVM的即时编译器完成了字节码到机器码的真正编译部分,同时缓存了字节码(如果需要)。

  4. 垃圾回收包含在JRE中。

1
令人惊讶的是,编译器是将源代码编译成字节码的工具。 - SJuan76
那么JIT编译器是什么,它恰好是JVM的一部分?编译是将字节码转换为机器码的过程,对吗? - eagertoLearn
那是另一个编译器,你永远不会直接使用它,并且并非总是运行。编译既可以从源代码到字节码,也可以从字节码到机器码。但是你将执行的唯一“Java编译器”是javac - SJuan76
而且javac并不执行将字节码转换为机器码的后半部分,那么在这种情况下它实际上是解释执行而不是编译吗? - eagertoLearn
2个回答

4
"字节码"编译是由Java编译器javac完成的。JDK(Java开发工具包)和JRE(Java运行环境)之间的区别在于,JDK包含javac,而JRE不包括。
将代码编译为字节码形式是真正的编译——字节码格式完全不像原始源代码。但是,在大多数硬件系统上运行字节码必须要么解释执行,要么进一步编译。(已经构建了一些实验性的硬件系统,可以直接执行某种形式的字节码)。
在大多数系统上,字节码开始被解释执行(由Java解释器完成,它是JRE的一部分)。随着代码的执行,“热点”部分的字节码将由“即时编译器”(JITC,也是JRE的一部分)编译,并以与C++或其他“直接编译”语言基本相同的效率执行。
需要注意的是,字节码格式非常类似于许多传统的“两阶段”/“优化”编译器使用的“中间语言”格式。在这个意义上,javac是传统编译器的前半部分。"

谢谢提供信息。字节码转换为机器码应该在某个层面上发生,以便CPU执行指令? - eagertoLearn
有点类似。通常,字节码会被一种称为“模拟器”的东西所“解释”,该模拟器假装成为一个“Java虚拟机”,通过“提取”各个字节码并执行所含动作来“执行”它们。这与将字节码转换为“本地”机器指令序列相对应,而正是这一点JITC实现的基本功能。 - Hot Licks

2

你的类文件是字节码。这些代码对于所有的Java虚拟机都是相同的。这就是关键,标准库/运行环境必须在某种程度上与平台相关(因为它桥接了这些差异),你不必担心这个问题。Java编译器生成字节码,它不是运行时环境的一部分。出于同样的原因,你的类和其他内容也不是编译器的一部分,它只是读取它们。

所以是的,.class文件=字节码形式。


可能是Java -P,我不确定,如果你在谷歌上搜索“Java反汇编”,会有所帮助。请记住,反汇编不等同于反编译。 - Alec Teal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接