实例分析Class字节码文件(二)
2017-10-10 00:17
183 查看
上篇必看:实例分析Class字节码文件(一)
包括:类级变量 + 实例级变量(不包括局部变量)
注:
① 类级变量 = 类变量 = 静态变量 【
②实例级变量 :没有
描述一个字段包含的方面有:
① 字段的作用域 :
② 是实例级变量还是类级变量(是否被
③ 可变性(是否被
④ 并发可见性(是否被
⑤ 是否可被序列化(
⑥ 字段数据类型(基本类型、对象、数组)
⑦ 字段名称
字段表结构如下:
access_flags结构如下:
所以
name_index : 字段的简单名称,值为对常量的引用
指向第5个常量 : ——> m
descriptor_index : 字段和方法的描述符,值为对常量的引用
指向第6个常量 : ——> I ,看到这个感觉有点问题,每个描述符都代表特殊的含义,如下:
descriptor_index一方面可以描述字段类型,如上表;另一方面还可以描述参数列表(包括数量、类型、顺序)和返回值。
注:
① 对于对象类型:用字符L和对象的全限定名来表示(
② 对于数组:每一个维度用一个“[” 表示
③ 用来描述方法时,按照参数列表,然后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号“()”之内
attributes_count: 用于存放一些额外的信息,字段都可以在属性表中描述>=0个额外信息。如果属性表计数器为0,则attribute_info不占用空间。
本例子中:
注:
① 字段集合中不会列出从超类或者父类中继承(或接口继承)出来的字段,单有可能列出原本java中不存在的字段(内部类)
②字段无法重载,两个字段的数据类型、修饰符不管是否相同,都必须使用不一样的名称,但是对于字节码来说,如果两个字段的描述符不一样,那字段重名就是合法的。
这个结构和字段表相似,
通过上表我们发现:并没有具体说明方法中的代码如何在字节码文件中存储的,其实是存放在方法属性表集合中一个名为“Code”的属性中。
注:在 方法表集合的前面,还有一个u2类型表示一共有几个方法;
在上一个的例子中值为:0x0002,代表有两个方法(inc()、)
然后才到方法表集合:
来看
注: 如果父类方法在子类中没有被重写(Override),方法表集合中就不会出现来自父类的方法信息。同样,有可能出现有编译器自动添加的方法,最经典的便是类构造器“”和实例构造器“”方法
四、字段表集合
字段表(field_info)集合用于描述接口或者类中声明的变量。包括:类级变量 + 实例级变量(不包括局部变量)
注:
① 类级变量 = 类变量 = 静态变量 【
static int a;】 存储在方法区;
②实例级变量 :没有
static修饰符,只能通过实例对象访问;存储在对象中;
描述一个字段包含的方面有:
① 字段的作用域 :
public、
private、
protected
② 是实例级变量还是类级变量(是否被
static修饰)
③ 可变性(是否被
final修饰)
④ 并发可见性(是否被
volatile修饰)
⑤ 是否可被序列化(
transient修饰)
⑥ 字段数据类型(基本类型、对象、数组)
⑦ 字段名称
字段表结构如下:
access_flags结构如下:
所以
access_flags应为 0x0002;查阅字节码文件,没问题
name_index : 字段的简单名称,值为对常量的引用
指向第5个常量 : ——> m
descriptor_index : 字段和方法的描述符,值为对常量的引用
指向第6个常量 : ——> I ,看到这个感觉有点问题,每个描述符都代表特殊的含义,如下:
descriptor_index一方面可以描述字段类型,如上表;另一方面还可以描述参数列表(包括数量、类型、顺序)和返回值。
注:
① 对于对象类型:用字符L和对象的全限定名来表示(
Ljava/lang/Object)
② 对于数组:每一个维度用一个“[” 表示
java.lang.String[][]-->[[Ljava/lang/String
int[]-->[I
③ 用来描述方法时,按照参数列表,然后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号“()”之内
void inc()--->()V
int indexOf(char[] source,
int sourceOff,
int sourceCount,
int targetOffset,
int targetCount,int fromIndex) -->([CII[CIII)I
attributes_count: 用于存放一些额外的信息,字段都可以在属性表中描述>=0个额外信息。如果属性表计数器为0,则attribute_info不占用空间。
本例子中:
attributes_count为 0x0000.
注:
① 字段集合中不会列出从超类或者父类中继承(或接口继承)出来的字段,单有可能列出原本java中不存在的字段(内部类)
②字段无法重载,两个字段的数据类型、修饰符不管是否相同,都必须使用不一样的名称,但是对于字节码来说,如果两个字段的描述符不一样,那字段重名就是合法的。
五、方法表集合
同样先来看方法表结构:这个结构和字段表相似,
access_flags包括:
通过上表我们发现:并没有具体说明方法中的代码如何在字节码文件中存储的,其实是存放在方法属性表集合中一个名为“Code”的属性中。
注:在 方法表集合的前面,还有一个u2类型表示一共有几个方法;
在上一个的例子中值为:0x0002,代表有两个方法(inc()、)
然后才到方法表集合:
来看
access_flags: 0x0001,很好理解
Acc_PUBLIC为真
name_index: 0x0007,指向第7个常量
<init>
descriptor_index: 0x0008 ,指向第8个常量()V
attributes_count: 0x0001,表示此方法的属性表集合有一项属性
attributes_info: 0x0009,指向第9个常量Code,说明此属性是方法的字节码描述
注: 如果父类方法在子类中没有被重写(Override),方法表集合中就不会出现来自父类的方法信息。同样,有可能出现有编译器自动添加的方法,最经典的便是类构造器“”和实例构造器“”方法
相关文章推荐
- 实例分析Class字节码文件(三)
- 实例分析Class字节码文件(一)
- 通过反射和class文件asm字节码分析方法是get或者set方法
- 实例分析Java Class的文件结构
- 实例分析Java class文件内容
- 实例分析Java Class的文件结构
- 实例分析Java Class的文件结构
- 实例分析Java Class的文件结构
- 实例分析Java Class的文件结构
- 实例分析 Java Class 的文件结构
- 创建一个自定义类加载器实现class文件(字节码文件)的加密解密的实例
- 实例分析Java Class的文件结构
- 实例分析Java Class的文件结构
- 实例分析Java Class的文件结构
- Java Class文件结构解析 及 实例分析验证
- 实例分析Java Class的文件结构
- 实例分析Java Class的文件结构
- java class 文件格式分析及实例完全标注
- 【thinkphp3.x】ThinkPHP/Lib/Core/Dispatcher.class.php文件分析
- Java 动态加载jar和class文件实例解析