java class文件结构

要深入理解class文件结构,请移步:http://blog.csdn.net/column/details/zhangjg-java-blog.html

package a;

/**
 * Created by leaves on 2016/11/8.
 */
public class Test2 {
    public static final int mStatic = 1111111111;
    public static int mStatic2 = 222222222;
    public String minstance = "asdf";
    public int anum = 1;


    public static void main(String[] args) {
      
        System.out.println("Hello, world");
    }


}

我们以下java文件为例,分析class文件的结构下面我们分析下他生成的class文件结构

class文件的数据的基本类型:

类 型

描 述

u1

1个字节,无符号类型

u2

2个字节,无符号类型

u4

4个字节,无符号类型

u8

8个字节,无符号类型



Class文件结构:

类 型

名 称

数 量

u4

magic

1

u2

minor_version

1

u2

major_version

1

u2

constant_pool_count

1

cp_info

constant_pool

constant_pool_count-1

u2

access_flags

1

u2

this_class

1

u2

super_class

1

u2

interfaces_count

1

u2

interfaces

interfaces_count

u2

fields_count

1

field_info

fields

fields_count

u2

methods_count

1

method_info

methods

methods_count

u2

attributes_count

1

attribute_info

attributes

attributes_count


我们分析下上面的class文件,对应各个字段的值如下


这里分析了前面几个字段,以及开始分析常量池,常量池其他的字段就不一一分析了

常量池中各个数据项通过索引来访问, 有点类似与数组, 只不过常量池中的第一项的索引为1, 而不为0, 如果class文件中的其他地方引用了索引为0的常量池项, 就说明它不引用任何常量池项。class文件中的每一种数据项都有自己的类型, 相同的道理,常量池中的每一种数据项也有自己的类型。 常量池中的数据项的类型如下表:

常量池中数据项类型类型标志类型描述
CONSTANT_Utf81UTF-8编码的Unicode字符串
CONSTANT_Integer3int类型字面值
CONSTANT_Float4float类型字面值
CONSTANT_Long5long类型字面值
CONSTANT_Double6double类型字面值
CONSTANT_Class7对一个类或接口的符号引用
CONSTANT_String8String类型字面值
CONSTANT_Fieldref9对一个字段的符号引用
CONSTANT_Methodref10对一个类中声明的方法的符号引用
CONSTANT_InterfaceMethodref11对一个接口中声明的方法的符号引用
CONSTANT_NameAndType12对一个字段或方法的部分符号引用


每个数据项叫做一个XXX_info项, 比如, 一个常量池中一个CONSTANT_Utf8类型的项, 就是一个CONSTANT_Utf8_info 。除此之外, 每个info项中都有一个标志值(tag), 这个标志值表明了这个常量池中的info项的类型是什么, 从上面的表格中可以看出, 一个CONSTANT_Utf8_info中的tag值为1, 而一个CONSTANT_Fieldref_info中的tag值为9 。


我们再看下后面的字段


我们分析这里的第一个字段field,field字段结构如下

access_flags(2byte 访问修饰符)  
name_index(2byte 存储字段名的常量表在常量池中的索引)
description_index(2byte 存储字段的所属类型的常量表在常量池中的索引)
attribute_count(2byte 属性表的数量)
attribute (属性)

这里前面两个字节是0019表示的是ACC_PUBLIC(0x0001) | ACC_STATIC(0x0008) | ACC_FINAL(0x0010)
name_index值为000c表示的字段名在常量池中的索引,对应的是 const #12 = Asciz       mStatic;
description_index 对应的是000d 表示的是 const #13 = Asciz       I; 代表是个整型
attribute_count 对应0001表示有一个attribute
 这里我们也可以跟源码中对应一下
 attribute是由attribute_info组成,attribute_info结构如下
 
 
 attribute_name_index 这里是000e,对应的是 const #14 = Asciz       ConstantValue;
 attribute_length 这里是00000002表示长队为2
 info对应的是000F表示常量池的索引,对应的是const #15 = int 1111111111;

这里开始分析了常量池的最后几个字段以及class文件中的剩下的结构,基本上就是按照对应的字段的结构来分析,主要都是通过常量池中的索引来表示的

可以参考一下几个网站:

http://blog.csdn.net/newthinker_wei/article/details/8028019

http://zhanjia.iteye.com/blog/1857709

http://blog.csdn.net/kobejayandy/article/details/39620833

然后可以用如下命令打印class文件的内容

javap -verbose Test2



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值