第3章 解析class文件

作为类(或者接口) [1] 信息的载体,每个class文件都完整地定义了一个类。为了使Java程序可以“编写一次,处处运行”,Java虚拟机规范对class文件格式进行了严格的规定。Java虚拟机规范(和本书)中所指的class文件,并非特指位于磁盘中的.class文件,而是泛指任何格式符合规范的class数据。

构成class文件的基本数据单位是字节,可以把整个class文件当成一个字节流来处理。

稍大一些的数据由连续多个字节构成,这些数据在class文件中以大端(big-endian)方式存储。

为了描述class文件格式,Java虚拟机规范定义了u1、u2和u4三种数据类型来表示1、2和4字节无符号整数.

相同类型的多条数据一般按表(table)的形式存储在class文件中。表由表头和表项(item)构成,表头是u2或u4整数。假设表头是n,后面就紧跟着n个表项数据。

Java虚拟机规范使用一种类似C语言的结构体语法来描述class文件格式。整个class文件被描述为一个ClassFile结构,代码如下:

ClassFile {

  u4 magic;
  u2 minor_version;
  u2 major_version;

  u2 constant_pool_count;
  cp_info constant_pool[constant_pool_count-1];

  u2 access_flags;
  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];
}

以为ClassFileTest.class例

package jvmgo.book.ch03;

public class ClassFileTest {
    public static final boolean FLAG = true;
    public static final byte BYTE = 123;
    public static final char X = 'X';
    public static final short SHORT = 12345;
    public static final int INT = 123456789;
    public static final long LONG = 12345678901L;
    public static final float PI = 3.14F;
    public static final double E = 2.71828D;

    public ClassFileTest() {
    }

    public static void main(String[] args) throws RuntimeException {
        System.out.println("Hello, World!");
    }
}
Classpy

魔数

很多文件格式都会规定满足该格式的文件必须以某几个固定字节开头,这几个字节主要起标识作用,叫作魔数(magic number)。class文件的魔数
是“0xCAFEBABE”。
Java虚拟机规范规定,如果加载的class文件不符合要求的格式,Java虚拟机实现就抛出java.lang.ClassFormatError异常。用classpy打开ClassFileTest.class文件,
可以看到,开头4字节确实是0xCAFEBABE

版本号

魔数之后是class文件的次版本号和主版本号,都是u2类型。

假设某class文件的主版本号是M,次版本号是m,那么完整的版本号可以表示成“M.m”的形式。
次版本号只在J2SE 1.2之前用过,从1.2开始基本上就没什么用了(都是0)。

主版本号在J2SE 1.2之前是45,从1.2开始,每次有大的Java版本发布,都会加1。

特定的Java虚拟机实现只能支持版本号在某个范围内的class文件。Oracle的实现是完全向后兼容的,比如Java SE 8支持版本号为45.0~52.0的class文件。

如果版本号不在支持的范围内,Java虚拟机实现就抛出java.lang.UnsupportedClassVersionError异常。

Java 8就是52,支持版本号为45.0~52.0的class文件。


00 0 00 034就是0 52 jdk8

常量池

常量池是个表,表头u2 ,这里是64-1个表项

类访问标志

常量池之后是类访问标志,
这是一个16位的“bitmask”,指出:
class文件定义的是类还是接口,访问级别是public还是private,等等。

ClassFileTest的类访问标志是0x21

类和超类索引

类访问标志之后是两个u2类型的常量池索引,分别给出类名和超类名。

class文件存储的类名 类似完全限定名,但是把点换成了斜线,Java语言规范把这种名字叫作二进制名(binary names)。

thisClass必须是有效的常量池索引。

本类

常量池第5个

superClass只在Object.class中是0,在其他class文件中必须是有效的常量池索引。


接口索引表

类和超类索引后面是接口索引表,表中存放的也是常量池索引,给出该类实现的所有接口的名字。
ClassFileTest没有实现接口,所以接口表是空的


ClassFileTest没有实现任何借口

字段和方法表

接口索引表之后是,


字段表和方法表

字段和方法的基本结构大致相同,差别仅在于属性表。

field_info {
  u2 access_flags;//访问标志
  u2 name_index;//常量池索引 名字
  u2 descriptor_index;//常量池索引  描述符

//属性表
  u2 attributes_count;
  attribute_info attributes[attributes_count];
}
public static final boolean FLAG = true;boolean描述符是Z

属性

方法表后面 是类的属性,除了Class有属性,field和method都有属性,method的Code属性还有属性
属性,按名字区别,结构是这样

attribute_info {
  u2 attribute_name_index;//属性名,常量池引用
  u4 attribute_length;//属性长度
//其他
}
只有一个类的属性,源码文件
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • 类文件结构 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式— 字节码( ByteCode ) 是构成平台无...
    好好学习Sun阅读 530评论 0 0
  • 庐阳怪,怪庐阳, 羚羊挂角诗词强, 简村响当当。 大山坡,山坡大, 鼓瑟吹笙响喇叭, 访者皆大咖。
    简村小吹阅读 326评论 5 13
  • Apple Watch终于到啦 好开心! 自己的愿望自己实现的感觉真好 感谢自己 感恩生活~从今起做个认真生活的人...
    Chen少阅读 142评论 0 0