1、关于访问标志(access_flag)
访问标志紧跟在常量池后,有两个字节(16位)大小表示,用来声明类或者接口层级的访问信息,比如标明:是一个class还是interface、这个类或接口是否被public修饰、是否由final修饰、是否定义为abstruct类型等等;
注意:访问标记除了标识类,也会标识方法和字段,会在介绍方法和字段的时候说明;
针对类和接口的访问标志规范定义如下:
名称 | 标志对应值 | 含义 |
---|---|---|
ACC_PUBLIC | 0x0001 | 是否public声明 |
ACC_FINAL | 0x0010 | 是否被声明final |
ACC_SUPER | 0x0020 | 均为真,即该为必须都为1 |
ACC_INTERFACE | 0x0200 | 是否是一个接口 |
ACC_ABSTRACT | 0x0400 | 是否为abstract类型 |
ACC_SYNTHETIC | 0x1000 | 表示该类为非用户代码产生 |
ACC_ANNOTATION | 0x2000 | 表示这是一个注释 |
ACC_ENUM | 0x4000 | 表示这是一个枚举 |
在.class文件中存储方式如下图:
实际上存储时,拥有哪个标志,就把对应上图中该标志的位置存为1,然后一起转成16进制存入.class文件中即可,比如public class,即标志位应该为:00000000 00000001 -> 0x 00 01
2、类索引、父类索引、接口索引集合
这三个部分确定了.class对应的类的继承关系与接口实现情况;
(1) 类索引(this_class)
类索引用来确定.class文件对应的类的全限定名,是一个u2的数据,紧跟在访问标志之后,指向一个常量池中的CONSTANT_Class_info类型。
(2) 父类索引(super_class)
父类索引用来确定.class文件对应的类的父类的全限定名,是一个u2的数据,紧跟在类索引之后,指向一个常量池中的CONSTANT_Class_info类型。
需要注意的是java中不允许多重继承,除了java/lang/Object之外,任何类都有父类,即类索引都必须指向一个CONSTANT_Class_info类型。
(3) 接口索引集合
用于确定.class文件对应的类所实现的接口,接口索引集合的入口(接口计数器)紧跟在父类引用之后,由于接口可以同时实现多个,所以接口索引是由:接口计数器(u2,interfaces_count)与接口索引表组成。
如果没有实现任何接口,那么interfaces_count为0,后面的接口索引表为空,不占用任何字节。