我想知道 .java 文件编译后得到的 .class 文件中的字节码和 .dex 文件中的字节码有何区别。它们的格式是否不同?如果是,那么它们分别是哪种格式。
JVM的.class文件包含JVM字节码,你可以阅读JVM规范中的第6章: Java虚拟机指令集来了解JVM字节码规范。
.dex文件包含Dalvik字节码。Dalvik是Android最初使用的虚拟机,现已被Android Runtime替代。原始版本的Dalvik是纯解释器,后来添加了编译器。ART最初是一个纯编译器,它在安装时就对你的代码进行了一次预编译(而不像JIT编译器那样每次运行都编译)。截至2020年,ART可以进行解释、AOT编译和JIT编译。
JVM字节码与Dalvik字节码之间的主要区别有:
你可以在这里找到关于构建过程的好信息。
引用:
所有Java代码,包括R.java和.aidl文件,都由Java编译器编译,并输出.class文件。
dex工具将.class文件转换为Dalvik字节码。您在模块构建中包含的任何第三方库和.class文件也会被转换为.dex文件,以便将它们打包到最终的.apk文件中。
@Andreas评论中的来源提供了Dalvik bytecode的技术洞察,这显然不是Java bytecode。
Android应用通常使用Java语言编写,并在Dalvik虚拟机(DVM)中执行,该虚拟机与传统的Java虚拟机(JVM)不同。
DVM由Google开发,针对移动操作系统的特点进行了优化(尤其是针对Android平台)。
在Dalvik中运行的字节码是通过使用转换工具dx将Java .class文件从传统的JVM字节码转换为dex格式而转换的。与DVM相反,JVM使用纯Java类文件。
JVM字节码由一个或多个.class文件组成(每个文件包含一个Java类)。在运行时,JVM会从相应的.class文件中动态加载每个类的字节码。而Dalvik字节码仅由一个.dex文件组成,其中包含应用程序的所有类。
在Java编译器创建JVM字节码之后,Dalvik dx编译器会删除所有.class文件并将它们重新编译为Dalvik字节码。然后dx将它们合并到一个.dex文件中。
Dalvik文档:http://source.android.com/devices/tech/dalvik/
Java文档:http://docs.oracle.com/javase/specs/
这两个文档完全不同。阅读后,您的所有疑问都将得到解决。
参见此答案:什么是.class和.dex文件之间的区别?
注意:虽然Java jar文件有许多类文件,但每个APK文件只有一个classes.dex文件。根据Google的说法,APK格式与类文件格式不同,出于性能和安全原因。