一、编译型语言和解释型语言的区别
1、编译型语言:
在编译型语言中,源代码会被整个编译成机器码或者中间代码(比如Java的字节码),生成可执行文件。
运行程序时,不需要再对源代码进行解释,而是直接执行生成的可执行文件。
典型的编译型语言包括C、C++等,它们在执行时需要依赖特定平台的编译结果。
2、解释型语言:
解释型语言的源代码在运行时会逐行或逐段被解释器解释执行,而不是提前编译成可执行文件。
解释型语言的执行速度通常比编译型语言慢,因为每次执行都需要解释器实时解释源代码。
典型的解释型语言包括Python、JavaScript等,它们不需要生成可执行文件,而是直接在解释器中运行源代码。
3、Java 程序从源代码到运行的过程:
- 所以说Java是解释和编译共存的一种语言。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class 文件),这种字节码必须由 Java 解释器来解释执行。
- 在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效,而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。
- 在Java中,JIT编译器是Java虚拟机的重要组成部分,负责将Java字节码转换成本地机器码,以便在特定平台上执行。在保持Java跨平台特性的同时,通过动态编译提高了程序的执行性能(JIT编译器在程序运行时动态生成本地机器码)。JIT编译器JIT编译器通常会使用各种优化技术,如方法内联、循环展开、常量传播等,以提高生成的机器码的效率和性能。支持动态特性是AOT不具有的。
二、class 文件的组成。
根据 Java 虚拟机规范,Class 文件通过 ClassFile 定义,ClassFile 的结构如下:
ClassFile {u4 magic; //Class 文件的标志u2 minor_version;//Class 的小版本号u2 major_version;//Class 的大版本号u2 constant_pool_count;//常量池的数量cp_info constant_pool[constant_pool_count-1];//常量池u2 access_flags;//Class 的访问标记u2 this_class;//当前类u2 super_class;//父类u2 interfaces_count;//接口数量u2 interfaces[interfaces_count];//一个类可以实现多个接口u2 fields_count;//字段数量field_info fields[fields_count];//一个类可以有多个字段u2 methods_count;//方法数量method_info methods[methods_count];//一个类可以有个多个方法u2 attributes_count;//此类的属性表中的属性数attribute_info attributes[attributes_count];//属性表集合
}
- 魔数(Magic Number):
.class文件的头四个字节是固定的魔数,用于识别文件是否为有效的Java类文件。通常情况下,这四个字节的数值为0xCAFEBABE。
u4 magic; //Class 文件的标志
- 版本号(Version):
魔数之后的四个字节表示.class文件的版本号,包括主版本号和次版本号。主版本号表示Java编译器的版本,次版本号表示编译器的次要版本。
u2 minor_version;//Class 的小版本号u2 major_version;//Class 的大版本号
- 常量池(Constant Pool):
常量池是.class文件中一个重要的部分,用于存储编译后的字节码中所用到的符号引用、字面量等信息。常量池中的内容包括类名、方法名、字段名、字符串常量等。
u2 constant_pool_count;//常量池的数量cp_info constant_pool[constant_pool_count-1];//常量池
- 访问标志(Access Flags):
访问标志指示了该类或接口的访问权限,比如public、private、protected等。
u2 access_flags;//Class 的访问标记
- 类信息:
包括类的名称、父类的名称、实现的接口等信息。
u2 this_class;//当前类u2 super_class;//父类u2 interfaces_count;//接口数量u2 interfaces[interfaces_count];//一个类可以实现多个接口
- 字段信息:
描述了类中的字段,包括字段名称、字段类型、访问标志等。
u2 fields_count;//字段数量field_info fields[fields_count];//一个类可以有多个字段
- 方法信息:
描述了类中的方法,包括方法名称、参数列表、返回值类型、访问标志等。
u2 methods_count;//方法数量method_info methods[methods_count];//一个类可以有个多个方法
- 属性表集合(Attributes):
u2 attributes_count;//此类的属性表中的属性数attribute_info attributes[attributes_count];//属性表集合
每个类、字段或方法都可以包含一些属性信息,比如源文件名、行号表、局部变量表等。
以上是.class文件的主要组成部分,它们共同构成了Java编译后的二进制表示形式,被Java虚拟机加载和执行。