了解class文件。
其实我们 编写的java文件 经过编译后 是.class文件(二进制文件),经过java虚拟机的类加载器加载到内存中被使用。现在我们 就研究一下
.class文件中字节码。其中的数据项 是按顺序紧密排列的,每项数据都有其固定长度。
1>是magic.占四个字节。是一个固定的值。
2>minor version 和 major version 各占2个字节。
3>constant pool
这个是重点详细讲一下。
常量池中放的什么东西呢?
答:类名,字段名 方法名 字段描述符 方法描述符 常量字符串 对当前 字段 方 法的 引用 信息 对其他类字段和方法的引用信息。主要分为 constant_utf8_info constant_NameAndType_info constant_Methodref_infoconstant_class_info constant _interfaceMethodref_info constant_Fieldref_info 等等 共11项 utf8 主要存储的是常 量字符串。比如类(接口)名 字段名 方法名 字段描述符 方法描述符 NameAndType 主要存储的是一个字段 或一个方法。他其实是由俩个 utf8 组成(name_index [指向 一个utf8 表示字段名或方法名],Type_index[指向一个utf8 , 表是一个字段描述符或方 法描述符])。
class 是有个name_index ,指向一个utf8_info. MethodRef 主要存储 方法的符号引用 InterfaceMethodref 主要存储接口的符号引用 Fieldref 主要存储一个字段的符号引 用。
对于什么是符号引用?
一个字段的符号引用就是通过这个引用能够间接了解到字段的类的信息,字段名的信 息,字段描述符的信息。或者说一个引用够让我们
了解到一个方法 或一个字段的所在类信息、方法名或字段名信息、方法或字段描述符 的信息那么我们就叫这个引用为一个方法或一个字段的符号引用。
对于什么是描述符:
(1)字段描述符:1.基本类型 int i; I int[] a;[I 2.引用类型 Object o;Ljava/lang/Object String str; Ljava/lang/String
(2)方法描述符:(参数类型1,参数类型2,...)方法返回类型
//特殊方法名 比如 构造方法<init> 静态初始化方法<cinit> 全限定名:比如 一个 类在 源代码中是Java.lang.Object 在.class文件的常量池中就是 Java/lang/object
4>fields-count 和 fields
fields-count 表示的是类中或接口中 字段的个数,注意fields-count 可能会比 源代码 中的定义字段多。占(2)个字节
fields 可以把他看为一个数组,每一个数组项都是一个fields_info.依次内容是 Access_flags,name_index,decriptor_index,attributes_count,attribute
其中name_index 指向的是常量池中的constant_utf8_info,decriptor_index指向的也 是constant_utf8_info.这里的attribute 中有3个属性constantValue、
deprecated、synthetic。(后面具体讲)。
5>Methods_count 和Methods
Methods_count 2个字节。
Methods 可以看为一个数组。每一个数组项都是一个Method_info 依次内容是 Access_flags,name_index,decriptor_index,attributes_count,attributes
同样,name_index 指向一个utf8_info,decriptor_index指向一utf8_info,attributes中 的属性有code ,deprecated,exceptions,synthetic。现在我们 讲一下属性:
1.code :
存 放方法的字节码指令。这个属性里面包含 好多内 容:依次是 Attributes_name_index,attribute_length,max_stack,
max_locals,code_length,code,exception_table_length,exception_table,attributes_co unt,attributes。max_index 表示 执行该方法的时候 栈帧的大小。
max_locals 执行该方法的时候 本地变量表的大小。
exception_table 是对异常表的描述 try catch finally 语句。可以看为一个数组。每一 个数组项为exception_info ,内容依次是:start_pc,end_pc,
handler_pc,catch_type.
start_pc 异常处理块 起始处相对于 code起始处 第一条指令的偏移量。
end_pc 异常处理块 结束处 相对于code 起始处第一条指令的偏移量。
handler_pc 异常处理块 中 catch块中第一条指令相对于code 起始处第一条指令的 偏移量。
大致意思就是若从start_pc 到end_pc 若出现异常,转到 handler_pc 处进行异常处 理。code属性中的attributes中也可以存放属性。有 LineNumberTable,LocalVariableTable
2.exceptions(注意该属性与code 平级 都在method 的attribute属性里面)
描述的是方法申明 可能抛出的异常。即throws声明的异常列表。
3.synthetic
Synthetic属性可以出现在filed_info中, method_info中和顶层的ClassFile中,表示 这个字段 方法或者类 不是由 用户源代码生成的,而是由机器自动编译
生成的。
4.departed
departed 属性表示该方法字段 或者类 已经过时。
在讲解一下constantValue 属性 出现在field_info中,是一个与字段相关的属性。每个 field_info中最多只能出现一个ConstantValue属性。 此外, 要注
意的是, 必须是静态字段才可以有ConstantValue属性。此外, 只有基本数据类型或 String类型的静态变量才可以存在ConstantValue属性,原因:首先回想一下
field_info的结构:Access_flags,name_index,decriptor_index,attributes_count,attribute。 attribute_info 中的constant_index指向一个常量池中
的 info.而常量池只有基本类型和string 类型,不会存在其他引用类型。
现在关于.class 文件的内容 大致讲完。