为什么字节码不是人类可读的?

Lau*_*835 2 java jvm

我对某个主题感到困惑:

当您编译 Java 或 Python 时,您将获得将在相应 VM 上运行的字节码。在上一个问题中,我问过为什么,当您在文本编辑器中打开 .pyc 或 .class 文件时,它显示为乱码而不是可读的字节码(加载、存储操作等)。

现在,我当时得到的答案是基于“这就像说如果你打开一个 .exe 文件并希望看到 x86 程序集”的论点,他们做了类比,我看到的字节码是“程序集”版本的不可读的真正字节码。

如果不是为了一件事,这将是可以的并且是有意义的。您无法将 exe 文件与字节码文件进行比较。一个 exe 文件已经编译成机器码。字节码文件不是。字节码文件被馈送到 VM,然后由 VM 解释它(通常使用 JIT)。

这意味着例如编写 JVM 的人(这只是一个软件本身),需要编写一个字节码解释器。我真的怀疑他们写了一个解释器来处理以下问题:

Java .class 文件:

在此处输入图片说明

我可能是错的,也许他们出于某种奇怪的原因编写了一个解释器来处理这种形式的字节码,但这似乎不太可能。但是,如果 JVM 处理字节码的“汇编”版本,那么这意味着循环是

.java -> .class(不可读)-> .class(在进入 JVM 时可读) 中间几乎没有任何意义。

在这一点上,我真的很困惑。

Lou*_*man 10

他们确实为这种形式的字节码编写了一个解释器。当然,他们将其读为字节,而不是 ASCII 字符,这使得它更有用。但是,例如,每个指令代码只需要一个字节,而不是例如五个来写入store

目标是在内存使用方面有一些紧凑的东西,但实际上并未编译为仅特定于一个设备的机器代码。Java 字节码或多或少是它自己的机器码形式。

但是,如果您想阅读它,请使用该javap命令将其反编译为更易读的形式。

  • 我认为没有必要强调紧凑性。重要的一点是,JVM 中的 M 代表“机器”,因此,将字节码设计为“机器可读”而不是“人类可读”是很简单的。目前还不清楚为什么 OP 认为人类可读的字节码可以帮助 JVM 这样的软件来处理它。尤其是“研究编译器设计”的人应该明白,处理人类可读的源代码是非常重要的。 (5认同)
  • 如果您将其作为字节而不是字母来读取,那么阅读起来并不困难。但是,例如,“istore_0”的字节码是字节“3b”,如果您尝试在记事本中打开它,它看起来像“;”。 (4认同)