class文件:编译后被JVM所执行的,不依赖特定硬件即操作系统的,二进制格式文件。
每个class文件对应与如下所示的ClassFile结构
1.General Information
在Class文件中是没有General Information这个信息的 它是一系列有关于这个类结构的总述
它包含了我们所熟知的 魔术,版本号,常量池数量,访问控制符,本类索引,父类索引,接口数量,字段数量,方法数量等。
2.Constant Pool
常量池是ClassFile中非常重要和核心的内容,ClassFile描述了一个Java类中绝大多数的信息。
常量池的基本结构
Constant Pool 主要由常量池数量和常量池数组两部分组成
JVM规定不使用第0个元素
JVM定义的11种常量
CONSTANT_Utf8_info
对应除CONSTANT_Utf8_info 之外的其他类型 JVM获取到tag标识便可以从JVM中的常量表中获取到起对应内容的长度
但CONSTANT_Utf8_info内容长度是不固定的,于是class文件在CONSTANT_Utf8_info元素内容之前划分除2个字节用于描述 UTF-8字符串编码的长度(tag+length+bytes),详情请参考上图数据类型结构表
3.Fields
fields_count和field_info_fields[fields_count]
fielsd_count 记录了当前类定义的变量总数(类变量+静态变量),结构为u2
fields 记录了每个变量的 变量名, 变量类型, 访问标识, 属性等
Descriptor: <Ljava/lang/String;>
JVM规范中每个变量都有描述信息(字段的数据类型,方法参数列表,返回值)
Method
method_info {u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attributes}
method中的三种方法
<init> 类的构造函数,一个类可以有多个<init>,当JVM决定实例化某个类时调用
<clinit>类初始化方法,Java编译器在编译期间动态添加类初始化方法(static变量,static{}),一个类只有一个,JVM决定加载某个类时调用<clinit>方法
普通方法:
虚拟机规范的9项属性
非静态方法 LocalNumberTable 默认第一个参数为 this
本小节只重点分享了 Java ClassFile中作者认为的重点,Java class字节码文件中还有很多属性,具体请参考《Java 虚拟机规范(Java SE 8版)》