JVM学习笔记之 -- Class文件结构(2)

前言

上篇我们说到,Class文件中最开始的4个字节为魔数(用来盘对是否是一个虚拟机可以接受的Class文件),紧接着的四位为主版本号和次版本号(各两位),之后为常量池部分(在常量池入口,及第9位和第10位代表常量池容量计数值)。之后的文件部分我们将在本文中提及。

访问标志

在常量池结束之后,紧接着两个字节表示访问标志(access_flags),此标志用于试别类或者接口层次的访问信息,例如这个Class时类还是接口;是否所定义为public类型;是否定义为abstract类型等。具体内容包括(如下表所示):
访问标志

注意上图中的8个标志会对应1个或多个为真,所以access_flag值为所有为真的标志的标志值的加和。

类索引、父类索引与接口索引集合

在Class文件中,由这三项数据来确定这个类的继承关系。类索引和父类索引都是一个u2类型数据,而接口索引集合是一组u2类型数据的集合(在Java中一个类只能有一个父类,可以实现多个接口)。在接口索引集合,入口的第一项u2类型数据表示接口计数器,即表示索引表的容量。其中类索引和父类索引会各自指向一个类型为CONSTANT_Class_info的类描述符常量,在通过CONSTANT_Class_info类型的常量中的索引值可以找到定义在CONSTANT_Utf8_info类型的常量中的全限定名字符串。

字段表集合

字段表(field info)用于描述接口或者类中声明的变量。字段(field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。对于类的修饰符,如:字段作用域(public、private、protected),可变性(final)等,我们将各个修饰符设置成布尔值,要么有,要么没有,很适合用标志位来表示。下图中列出了字段表的最终格式:
字段表结构

字段修饰符放在access_flags项目中,他与类中的access_flags项目非常相似,具体的对应值如下图所示:
字段访问标志在access_flags标志之后的是:name_index 和 descriptor_index。它们都是对常量池的引用,分别代表着字段的简单名称以及字段和方法的描述符。在继续进行之前,我们先了解几个概念:

“全限定名”:这个词在前面已经出现了很多次,那么什么是全限定名呢?例如“org/fenixoft/clazz/TestClass”就是一个类的全限定名,只是把类全名中的"."换成了“/”而已,在末尾添加一个“;”来结束一个全限定名。

“简单名称”:是指没有类型和参数修饰的方法或者字段名称,例如一个类中有inc()方法和m字段,则他们的简单名称分别是“inc”和”m“。

"描述符":是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返
回值,所有的类型用一个大写字母来表示。

描述符

对于数组int[],用[I来表示。方法void inc()的描述符为()V。例如方法 int indexOf(char[] source, int sourceOffest, int sourceCount, char[] target, int targetOffest, int targetCount, int formIndex)的描述符为“([CII[CIII)I”。如果声明为“final static int m=123;”,则可能会存在一项名称为ConstantValue的属性,其值指向常量123.

在字段表集合入口,和以往一样,有一个u2类型数据作为容量计数器field_count,表示这个类有几个字段表数据。注意,字段表集合不会列出从超累或者父接口中集成而来的字段,但有可能列出原本Java代码中不存在的字段,譬如在内部类中为了保持对外部类的访问性,会自动添加指向外部类实例的字段。

方法表集合

Class文件存储格式中对方法的描述与对字段的描述几乎才用了完全一致的方式,如下图所示:方法表集合

与字段表集合相对应的,如果父类方法在子类中没有被重写(Override),放发表集合中就不会出现来自父类的方法信息。在Java中,要重载(Overlaod)一个方法,除了要与原方法具有相同的简单名称之外,还要求必须拥有一个与原方法不同的特征签名

特征签名就是一个方法中各个参数在常量池中的字段符号引用的集合。

Java语言层面的方法特征签名:
特征签名 = 方法名 + 参数类型 + 参数顺序;
JVM层面的方法特征签名:
特征签名 = 方法名 + 参数类型 + 参数顺序 + 返回类型

也就是因为返回值不会包含在特征签名中,因此Java语言里面是无法仅仅依靠返回值的不同来对一个己有方法进行重载。而在Class文件格式中,如果两个方法有相同的名称和特征签名,但是返回值不同,那么它们可以共存于一个Class文件中。

参考:《深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值