编译与翻译的区别,“编译”Java为字节码?

8

我的理解如下,定义如下:

翻译 - 使用某种语言编写代码,生成其他语言的代码。

编译 - 翻译成机器码。

机器码 - 直接给CPU的指令。

现在,来自docs.oracle.com:

javac - Java编程语言的编译器

编译器...?我认为它应该是Java 翻译器,因为它正在生成一种不是机器码的代码。字节码需要解释器(JVM)才能运行,所以它绝对不是机器码。

来自Wikipedia

Java应用程序通常会被编译成字节码

同样地,根据定义,我认为Java被翻译成字节码。在互联网上有许多类似的例子,我认为这方面存在一些混淆或者是我自己遗漏了某些东西。
请问能否澄清一下这个问题?编译和翻译之间有什么区别?

你的定义是错误的。 - SK-logic
4个回答

9

一切都是定义问题,对于“编译”这个词并没有一个单一的被广泛接受的定义。在你看来,编译是将某种语言的源代码转换为本地代码;因此,不生成机器代码的转换过程不应该被称为“编译”。而在我看来(显然,也是javac文档编写者的看法),应该这样称呼。

实际上有很多不同的术语:翻译、编译、反编译、汇编、反汇编等等。

个人认为,将所有这些术语归为“编译”是有道理的,因为所有这些过程都有很多共同点:

  • 它们将一个形式语言的代码转换为另一个形式语言的代码。
  • 它们尽可能保留输入代码的语义。
  • 它们的设计非常相似,都有前端、后端和可能的优化器(在这里了解更多关于编译器结构的知识)。我曾经看过javac和本地编译器的内部结构,它们非常相似。

此外,你对“生成本地代码”的定义存在问题:

  • 关于那些可以生成汇编代码但不会将其转换为机器码而留给外部程序(通常称为“汇编器”)的编译器,您如何评定它们的“编译器”定义?您会否因为最后这个微不足道的步骤而否认它们是编译器?
  • 你怎么分类“机器码”?如果明天能够原生运行Java字节码的处理器出现了呢?

但这只是我的观点。我认为在外界,最被广泛接受的定义是:

  • 编译是将高级语言代码转换为低级语言代码的过程。例如:Java到Java字节码,或C到x86机器码。
  • 反编译是将低级语言代码转换为高级语言代码的过程 - 实际上是编译的相反过程。例如:Java字节码到Java。
  • 翻译源到源编译是将某种语言的代码转换为另一种相似“级别”的语言的过程。例如:ARM到x86,或C到Java。当两种语言实际上是同一语言的不同版本(例如Javascript 6到Javascript 5)时,也使用术语转译器
  • 汇编是将某种汇编语言代码转换为机器码的过程。
  • 反汇编根据上下文可以是反编译的同义词或汇编的相反过程。

根据这些定义,javac肯定可以被视为编译器。但再次强调,这都取决于定义:从技术角度来看,许多这样的操作有很多共同点。


5

Java编译器的结果是机器码。虚拟机和物理机器之间的差别并不重要(否则,你可以争辩说在Mac系统上编译x86代码是翻译,因为x86代码不是Mac机器码)。


2
自2006年起,Mac使用x86平台。 - Mark Rotteveel
为什么不从C++翻译成x86,然后从x86编译成PowerPC机器码呢?我认为这比将字节码等同于机器码更好。x86机器码怎么可能与字节码处于同一类别中... - Adam Stelmaszczyk
我认为我们对“语言”的定义不同。我认为“语言”不一定是基于文本的。语言是在符号上操作的。01或文本(或声音)都无所谓。人类也可以阅读01指令。 - Adam Stelmaszczyk
那么,按照这个定义,一切都是语言,你永远不编译只进行翻译。如果这个定义适用于所有情况,那么它就没有什么用处了。 - SJuan76
更有用的是将字节码等同于机器码吗?如果我们有5个虚拟机呢?在抽象层面上,我们首先编写一段代码,然后将其转换为较不抽象的第二段代码,以此类推...因此,我们应该说“编译”而不是“翻译”?我认为这更加令人困惑。在那5个虚拟机模型中的最后一次转换将是一次编译(根据我给出的定义)。 - Adam Stelmaszczyk
显示剩余4条评论

1
“编译器是一种计算机程序(或一组程序),它将用一种编程语言(源语言)编写的源代码转换为另一种计算机语言(目标语言),通常具有二进制形式的目标代码。”

http://en.wikipedia.org/wiki/Compiler

所以编译并不意味着输出是机器码。例如,早期的C++编译会生成一个C程序,然后需要再次编译成机器码。当然,任何好的编译器都会将这些独立的步骤隐藏起来,但它们仍然存在。
现在我知道至少NesC编译器也执行同样的过程。
可以构建运行JVM字节码的机器,实际上,《结构化计算机组织》一书中的一些章节描述了如何做到这一点。

http://www.amazon.com/Structured-Computer-Organization-5th-Edition/dp/0131485210


编译是否等同于翻译?那么,所有的翻译器都应该被称为编译器吗? - Adam Stelmaszczyk
1
翻译更为通用,我可以从英语翻译成西班牙语,但在计算机语言领域,是的,绝对需要编译。 - LtWorf

1
“编译器……?我认为它是Java翻译器,因为它生成的代码不是机器码。字节码需要解释器(JVM)才能运行,所以它绝对不是机器码。”
“JVM是Java虚拟机,是一台计算机,其机器码称为Java字节码(字节码中的每个“字节”都是JVM机器指令)。您可以通过阅读JVM规范来了解更多信息。从这里开始:https://docs.oracle.com/javase/specs/
“此外,JVM不是解释器;它是一台计算机的定义。某些JVM实现包括即时(JIT)编译器、预编译(AOT)编译器、自适应编译器(例如Hotspot),甚至解释器(虽然我20年来没有亲眼见过Java解释器)。 ”
大多数刚开始学习编译器的人不明白的是,现在已经没有生成“机器码”的编译器了。它们都会生成一些中间形式(例如由特定操作系统定义),然后由操作系统加载和处理。

如今,几乎所有编译出来的程序都需要一个庞大的操作系统来对其进行处理、分割和粘合,以使其成为操作系统所拥有和管理的部分。

即使是 C 语言也不能再将代码编译成实际的机器可执行文件而不越过规定的范围。(从零开始编写一个真正的、可工作的引导程序,然后回到我这里。)


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