I、无关性
实验语言无关性的基础仍然是虚拟机和字节码存储格式。Java语言不与包括Java语言在内的任何程序语言绑定(如:Kotlin、Clojure、Groovy、JRuby、JPhthon,Scale等),它只与Class文件绑定。
II、Class类文件结构
1、8字节为基础单位
2、数据类型
类型 | 描述 |
---|---|
无符号数 | 以u1、u2、u4、u8来表示1、2、4、8个字节的无符号数。用来描述数字、索引引用、数量值或按照UTF-8编码构成的字符串 |
表 | “_info”结尾。描述有层次关系的复合结构的数据。整个Class文件本质上也是一张表 |
3、文件格式
类型 | 名称 | 数量 |
---|---|---|
u4 | magic | 1 |
u2 | minor_version | 1 |
u2 | major_version | 1 |
u2 | contsant_pool_count | 1 |
cp_info | contsant_pool | contsant_pool_count-1 |
u2 | access_flag | 1 |
u2 | this_class | 1 |
u2 | super_class | 1 |
u2 | interface_count | 1 |
u2 | interfaces | interface_count |
u2 | fields_count | 1 |
field_info | fields | fields_count |
u2 | methods_count | 1 |
method_info | methods | methods_count |
u2 | attributes_count | 1 |
attribute_info | attributes | attributes_count |
3-1魔数(magic)
确定这个文件是否能为一个被虚拟机接受的Class文件。
值为:0xCAFEBABE
3-2次版本号minor-version和主版本号major-version
即使文件格式未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件
3-3常量池constant_pool
1、常量池主要存放:字面量和符号引用
2、字面量:接近Java的常量概念,如文本字符串、被声明为final的常量值等
3、符号引用:
3.1、被模块导出或者开放的包
3.2、类和接口的全限定名
3.3、字段的名称和描述符
3.4、方法的名称和描述符
3.5、方法句柄和方法类型
3.6、动态调用点和动态常量
4、Java中方法、字段名最大长度是64KB
3-4访问标示access_flags
识别一些类或接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类;
是否定义为abstract类型;如果是类的话,是否被声明为final等等。
3-5类索引(this_class)、父类索引(super_class)与接口索引集合(interfaces)
Class文件中由这3项数据来确定该类的继承关系。类索引确定这个雷的全限定名。父类索引确定这个类的父类的全限定名。
3-6字段表(field_info)集合
1、描述接口或类中声明的变量。包括类级变量和实例级变量,但不包括在方法内部声明的局部变量。
2、字段修饰符:
2.1、字段的作用域,public、private、protected等
2.2、是实例变量还是类变量(static)
2.3、可变性(final)
2.4、并发可见性(volatile,是否强制从主内存读写)
2.5、可否被序列化(transient)
2.6、字段数据类型(基本类型、对象、数组等)
3、例
int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex)
的描述符为:
([II[CIII)I
3-7方法表(method_info)集合
构成:访问标示、名称索引、描述符索引、属性表集合
如果父类方法在子类中没有被重写,方法表集合中就不会出现来自父类的方法信息。
如果两个方法有相同的名称和特征签名,但返回值不同,那么也是可以合法共存于一个Class文件中。
3-8属性表(attribute_info)集合
1、Code属性:Java程序方法体里边的代码经过Javac编译器处理之后,最终变为字节码存储在Code属性内。
2、Exceptions属性:列举方法中可能抛出的受检异常,也就是方法描述时在throws关键字后面列举的异常。
3、LineTableNumber属性:描述Java源码行号与字节码行号之间的对应关系。
4、LocalVariableTable和LocalVariableTypeTable属性:用于描述栈帧中局部变量表的变量与Java源码中定义的变量之间的关系。
5、SourceFile和SourceDebugException属性:SourceFile属性记录生成这个Class文件的源码文件名称;SourceDebugException属性用于存储额外的代码调试信息。
6、ConstantValue属性:通知虚拟机自动为静态变量赋值。
7、InnerClasses属性:记录内部类与宿主类之间的关系。
8、Deprecated和Synthetic属性:Deprecated表示某个类、字段或方法已经被程序作者定为不再推荐使用,@deprecated注解设置;Synthetic代表此字段或方法不是由Java源码直接产生的,而是由编译器自行添加的。
9、StackMapTable属性:代替以前比较耗性能的基于数据流分析的推导验证器。
10、Signature属性:记录泛型的签名信息。
Java语言的泛型采用的是擦除法实现的伪泛型,字节码(Code属性)中所有的泛型信息编译(类型变量、参数化类型)在编译之后都通通被擦除掉。
11、BootstrapMethods属性:保存invokedDynamic指令引用的引导方法限定符。
12、MethodsParameters属性:记录方法的各个形参名称和信息。
13、模块化相关属性:支持模块化功能;Java9-;Module、ModulePackages、ModuleMianClass
14、运行时注解相关属性:
RuntimeVisibleAnnotations、RuntimeInVisibleAnnotations、RuntimeVisibleParameterAnnotations、RuntimeInvisibleParameterAnnotations、RuntimeVisibleTypeAnnotations、RuntimeInvisibleTypeAnnotations。
RuntimeVisibleAnnotations记录了类、字段或方法的声明上记录运行时可见的注解,当我们使用反射API来获取类、字段或方法上的注解时,返回值就是通过这个属性来取到的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。