欢迎来到 IT实训基地-南通科迅教育
咨询电话:0513-81107100
细说JVM系列:Class文件结构
2017/4/18
南通科迅教育
424
南通Web前端培训排名_费用_教程

Class文件结构

Class文件的结构并不是一成不变的,随着java虚拟机的不断发展,总是不可避免的会对class文件结构做出一些调整,但是其基本结构和框架是非常稳定的。class文件的总体结构如图所示:

\

在我在看这块内容的时候,我在想我怎么结合我已有的概念去理解这个东西:其实Class文件就像用jvm的编程语言的语法编写成的一种代码文件。这种编程语言不是我们写的,而是编译成的,既然是一种编程语言必然有基本数据类型,数据结构等等这些编程语言基本的东西。为啥这里Class文件包括这些部分,你想呀,Class文件来自java文件,java文件都是类,因此要完成这种编译,最重要的是将java的类转化为class文件对应的部分。java的类有啥:父类、子类、接口、属性、方法等等,然后对象的去看对应的部分即可。

根据java虚拟机规范的定义,一个class文件可以非常严谨的被描述为:

\

1)u4 magic 表示魔数,并且魔数占用了4个字节,魔数到底是做什么的呢?它其实就是表示一下这个文件的类型是一个Class文件,而不是一张JPG图片,或者AVI的电影。而Class文件对应的魔数是0xCAFEBABE.

2)u2 minor_version 表示Class文件的次版本号,并且此版本号是u2类型的无符号数表示。

3) u2 major_version 表示Class文件的主版本号,并且主版本号是u2类型的无符号数表示。major_version和minor_version主要用来表示当前的虚拟 机是否接受当前这种版本的Class文件。不同版本的Java编译器编译的Class文件对应的版本是不一样的。高版本的虚拟机支持低版本的编译器编译的 Class文件结构。比如Java SE 6.0对应的虚拟机支持Java SE 5.0的编译器编译的Class文件结构,反之则不行。

4) u2 constant_pool_count 表示常量池的数量。这里我们需要重点来说一下常量池是什么东西,请大家不要与Jvm内存模型中的运行时常量池混淆了,Class文件中常量池主要存储了字 面量以及符号引用,其中字面量主要包括字符串,final常量的值或者某个属性的初始值等等,而符号引用主要存储类和接口的全限定名称,字段的名称以及描 述符,方法的名称以及描述符,这里名称可能大家都容易理解,至于描述符的概念,放到下面说字段表以及方法表的时候再说。另外大家都知道Jvm的内存模型中 有堆,栈,方法区,程序计数器构成,而方法区中又存在一块区域叫运行时常量池,运行时常量池中存放的东西其实也就是编译器长生的各种字面量以及符号引用, 只不过运行时常量池具有动态性,它可以在运行的时候向其中增加其它的常量进去,最具代表性的就是String的intern方法。

5)cp_info 表示常量池,这里面就存在了上面说的各种各样的字面量和符号引用。放到常量池的中数据项在The Java Virtual Machine Specification Java SE 7 Edition 中一共有14个常量,每一种常量都是一个表,并且每种常量都用一个公共的部分tag来表示是哪种类型的常量。

下面分别简单描述一下具体细节等到后面的实例 中我们再细化。

?
1
2
3
4
5
6
7
8
9
10
11
CONSTANT_Utf8_info      tag标志位为1,   UTF-8编码的字符串
CONSTANT_Integer_info  tag标志位为3, 整形字面量
CONSTANT_Float_info     tag标志位为4, 浮点型字面量
CONSTANT_Long_info     tag标志位为5, 长整形字面量
CONSTANT_Double_info  tag标志位为6, 双精度字面量
CONSTANT_Class_info    tag标志位为7, 类或接口的符号引用
CONSTANT_String_info    tag标志位为8,字符串类型的字面量
CONSTANT_Fieldref_info  tag标志位为9,  字段的符号引用
CONSTANT_Methodref_info  tag标志位为10,类中方法的符号引用
CONSTANT_InterfaceMethodref_info tag标志位为11, 接口中方法的符号引用
CONSTANT_NameAndType_info tag 标志位为12,字段和方法的名称以及类型的符号引用

6) u2 access_flags 表示类或者接口的访问信息,具体如下图所示:

\

7)u2 this_class 表示类的常量池索引,指向常量池中CONSTANT_Class_info的常量

8)u2 super_class 表示超类的索引,指向常量池中CONSTANT_Class_info的常量

9)u2 interface_counts 表示接口的数量

10)u2 interface[interface_counts]表示接口表,它里面每一项都指向常量池中CONSTANT_Class_info常量

11)u2 fields_count 表示类的实例变量和类变量的数量

12) field_info fields[fields_count]表示字段表的信息,其中字段表的结构如下图所示:

\

上图中access_flags表示字段的访问表示,比如字段是public,private,protect 等,name_index表示字段名 称,指向常量池中类型是CONSTANT_UTF8_info的常量,descriptor_index表示字段的描述符,它也指向常量池中类型为 CONSTANT_UTF8_info的常量,attributes_count表示字段表中的属性表的数量,而属性表是则是一种用与描述字段,方法以及 类的属性的可扩展的结构,不同版本的Java虚拟机所支持的属性表的数量是不同的。

13) u2 methods_count表示方法表的数量

14)method_info 表示方法表,方法表的具体结构如下图所示:

\
其中access_flags表示方法的访问表示,name_index表示名称的索引,descriptor_index表示方法的描述 符,attributes_count以及attribute_info类似字段表中的属性表,只不过字段表和方法表中属性表中的属性是不同的,比如方法 表中就Code属性,表示方法的代码,而字段表中就没有Code属性。其中具体Class中到底有多少种属性,等到Class文件结构中的属性表的时候再 说说。

15) attribute_count表示属性表的数量,说到属性表,我们需要明确以下几点:

属性表存在于Class文件结构的最后,字段表,方法表以及Code属性中,也就是说属性表中也可以存在属性表
属性表的长度是不固定的,不同的属性,属性表的长度是不同的

举例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
packagecom.ejushang.TestClass;
 
publicclassTestClassimplementsSuper{
 
privatestaticfinalintstaticVar =0;
 
privateintinstanceVar=0;
 
publicintinstanceMethod(intparam){
 returnparam+1;
 }
 
}
 
interfaceSuper{ }

通过jdk1.6.0_37的javac 编译后的TestClass.java对应的TestClass.class的二进制结构如下图所示:

\

77
关闭
先学习,后交费申请表
每期5位名额
在线咨询
免费电话
QQ联系
先学习,后交费
TOP
您好,您想咨询哪门课程呢?
关于我们
机构简介
官方资讯
地理位置
联系我们
0513-91107100
周一至周六     8:30-21:00
微信扫我送教程
手机端访问
南通科迅教育信息咨询有限公司     苏ICP备15009282号     联系地址:江苏省南通市人民中路23-6号新亚大厦三楼             法律顾问:江苏瑞慈律师事务所     Copyright 2008-