JVM Class详解之一

  • 时间:
  • 浏览:5

编译成class文件后后,只用javap -verbose HelloWorld.class 指令都都能能查看当前class的内容



一同使用UE打开class文件



大家来一同看下ClassFile底部形态



前另4个字节为魔数,也只是我0xCAFEBABE,这里都不 十六进制



魔数后另4个字节为副版本号,这里副版本号是0



主版本号0x0033,转为十进制,主版本号是51 标示当前class是通过jdk 1.7编译的,0x32是jdk1.6 0x31是jdk1.5



这另4个字节是常量池计数器,常量池的数量为0x001A,转为十进制是26,也只是我说常量池索引为1~26

这里土土办法access flags 为 00 01 说明土土办法为public的

name_index为00 07,土土办法名指向常量中第7个常量土土办法名为, descriptor_index为常量池第8个常量()V





attributes_count 为 00 01标示你是什么 土土办法的属性表集合包含另4个属性。属性名称为接下来2位0x0009,指向常量池中第9个常量:Code

接下来4位为 00 00 00 3D标示Code属性值的字节长度为3D,接下来为00 02标示该土土办法的操作数栈的深度1最大值为2.

00 01标示该土土办法的局部变量占用空间为1.



接下来4位00 00 00 0B 为机器编译生成字节码指令的长度为11,底下1另4个字节只是我字节码指令(字节码指令可查询虚拟机字节码指令表),这里字节码指令长度用另4个字节标示,所有字节码指令超长Class编译会失败的。

再接下来为 00 00标示Code属性异常表结合为空。

再底下为 00 02,,说明Code包含另4个属性, 00 10即为Code属性第另4个属性的属性名成指向常量池中第16个常量

接下来的00 00 00 0E 标示LinueNumberTable属性值所占字节长度为15.接下来2位 00 03标示该line number table包含六个line number table表,start pc为 00 00 line number第 00 0另4个为00 04 第 00 0另4个为 00 0A 

再底下的 00 01又是第六个土土办法的access flags,接着后后结速了了第六个土土办法。



常量池底下紧跟的另4个字节是Access Flag,你是什么 表示用于标示类或接口层次的访问信息,如你是什么 Class是类还是接口,有无为public类型,有无定义为abstrace类型。

标志名称 标志值 含义

ACC_PUBLIC 0x0001 有无为public类型

ACC_FINAL 0x0010 有无被声明为final,不需要 类可设置

ACC_SUPER 0x0020 有无允许使用invokespecial字节码指令,JDK1.2后后编译出来的类你是什么 标志为真

ACC_INTERFACE 0x050 标识这是另4个接口

ACC_ABSTRACT 0x050 有无为abstract类型,对于接口和抽象类,此标志为真,其它类为假

ACC_SYNTHETIC 0x50 标识别你是什么 类从不由用户代码产生

ACC_ANNOTATION 0x50 标识这是另4个注解

ACC_ENUM 0x500 标识这是另4个枚举

大家这里0021标示为public Class



底下的0x07对应tag找到是CONSTANT_Class,标示接下来的是另4个class的信息。底下的 00 02 是class的name_index 标示指向常量池的第六个常量。大家再看第六个常量



第六个常量是01开头,大家查看常量类型表中对应是Utf-8,再按照utf-8的底部形态,底下的00 0A代表了你是什么 utf-8的长度这里长度转换为10进制是11,底下紧跟着utf-8的实际内容





再底下0x 07,是常量池的下另4个产量,也是另4个class信息,底下跟00 04,name_index执行常量池的

第另4个常量。



第另4个常量又是utf-8,底下长度为 0x10 十进制为16,接下来的为实际内容



接下来都都都能能按照此土土办法分析。

直观结果都都能能通过javap指令查看

Class文件是一组以8位字节为基础的二进制流,各个数据项目按照严格顺序紧凑排列在Class文件中。

所有的16位,32位,64位长度的数据将被构造成另4个,另4个,8个字节单位来标示。



method_count: 00 03 有六个土土办法

methods:土土办法表集合

access flags的定义见下表

常量池计数器底下紧跟着只是我常量池的内容

所有的常量池项都具有如下通用格式:

accessFlags为 00 00 当时当前字段无修饰符

字段修饰符格式如下

为另4个字节



这里为00 01,指向常量池中第另4个常量,后后大家分析过常量池中第另4个常量为Class类型,内容指向第六个常量UTF-8的HelloWorld。

标示当前名为HelloWorld

接下来的是类索引,父类索引与接口索引集合

this_class,super_class,interfaces_count,interfaces



表示接口数量为0

也是另4个字节



指向常量中第另4个常量,对应内容为java/lang/Object

00 01 标示字段数量为1

字段表的格式如下

首先看Class中包含那此信息简单的说所有java文件包含的信息class文件都不 ,编译器帮大家将java文件转化成了JVM能看懂的class格式而已

name_index为 00 05指向常量池中的第六个常量

第六个常量为str,变量名为str



descriptor_index指向常量池第6个变量,为Ljava/lang/String类型

attributes_count(属性计数器,占2字节,0x0000,所以所以该字段没有 额外不需要 描述的信息)