魔数
u4+
版本号u4(次版本号u2,主版本号u2)+
常量池(常量池容量计数器u2,(类型标志位u1+不同类型常量的结构))+
访问标志u2+
类索引u2+
父类索引u2+
接口索引集合u2+
字段表集合(容量计数器u2,标志位u2,简单名称u2,描述符u2,属性表容量计数器u2,(不同属性表结构))+
方法表集合(访问标志u2,名称索引u2,描述符索引u2,
属性表容量计数器u2,(不同属性表结构))
CONSTANT_Utf8_info型常量的结构
1、魔数(u4)
用于确定该Class文件是否能够被虚拟机接收。值为CA FE BA BE。
2、版本号(u4)
分为次版本号和主版本号,表示该Class文件可以被大于或者等于该J
DK的版本号的虚拟机执行。
3、常量池
3.1常量池容量计数值(u2)
表示常量池中有多少项常量。索引值从1开始。
3.2常量
有十一种类型的常量,每种常量的结构不用。
常量表类型 | 标志值(u1) | 描述 |
CONSTANT_Utf8 | 1 | UTF-8编码的Unicode字符串 |
CONSTANT_Integer | 3 | int类型的字面值 |
CONSTANT_Float | 4 | float类型的字面值 |
CONSTANT_Long | 5 | long类型的字面值 |
CONSTANT_Double | 6 | double类型的字面值 |
CONSTANT_Class | 7 | 对一个类或接口的符号引用 |
CONSTANT_String | 8 | String类型字面值的引用 |
CONSTANT_Fieldref | 9 | 对一个字段的符号引用 |
CONSTANT_Methodref | 10 | 对一个类中方法的符号引用 |
CONSTANT_InterfaceMethodref | 11 | 对一个接口中方法的符号引用 |
CONSTANT_NameAndType | 12 | 对一个字段或方法的部分符号引用 |
CONSTABT_Class_info型常量的结构
类型 | 名称 | 数量 |
u1 | tag | 1 |
u2 | name_index | 1 |
类型 | 名称 | 数量 |
u1 | tag | 1 |
u2 | length | 1 |
u1
|
bytes
|
length
|
4、访问标志(u2)
用于识别一些类或者结构层次的访问信息,包括:这个类是否还是接口;是否定义为public类型;是否定义为abstract类型等。值为A|B。
5、类索引(u2)
确定类的全限定名。
6、父类索引(u2)
确定这个类的父类的全限定名。除了java.lang.Object外,所有的java父类索引都不为0。
7、接口索引集合(u2)
描述这个类实现了哪些接口。
8、字段表集合
8.1标志位(u2)
描述变量的数据类型。
8.2名称索引
描述变量的简单名称。
8.3描述符索引
描述变量的数据类型、方法的参数列表和返回值
8.4属性容量表计数器
表示接下里有多少个变量。
9、方法表集合
和字段表集合类似。
10.属性表——在字段表集合和方法表集合的最后
类型 | 名称 | 数量 | 说明 |
u2 | attribute_name_index | 1 |
属性表的类型
|
u2 | attribute_length | 1 |
属性表的长度
|
u1
|
info
|
attribute
|
不同属性表的结构不一样
|
属性表类型
例子:
(1)JDK为jdk1.6.0_43
(2)程序
package com.pandawork.test;
public class TestClass {
private int m;
public int inc(){
return m+1;
}
}
(2)class文件如下:
(3)使用javap打印出的常量值
分析结果:
具体分析结果请点击这里(因为图片上传很麻烦)