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 来获取类、字段或办法上的注解时,返回值就是通过这个属性来取到的。