JVM专题——类文件结构(2)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

cp_info        constant_pool[constant_pool_count-1];//常量池

常量池的数量是 `constant_pool_count - 1` (常量池计数器是从1开始计数的, 常量池索引为0表示 “不引用任何一个常量池项”)


常量池中主要存放两大类常量: **字面量** 和 **符号引用** . 字面量比较接近于 Java 语言中的常量概念, 而符号引用属于编译原理的概念, 主要包括以下几类变量


* 被模块导入或者开放的包
* 类和接口的全限定名
* 字段的名称和描述符
* 方法的名称和描述符
* 方法句柄和方法类型
* 动态调用点和动态常量


常量池中每一个常量都是一个表, 到JDK13版本目前有17个不同类型的常量




| 类型 | 标志 | 描述 |
| --- | --- | --- |
| CONSTANT\_Utf8\_info | 1 | UTF-8编码的字符串 |
| CONSTANT\_Integer\_info | 3 | 整型字面量 |
| CONSTANT\_Float\_info | 4 | 浮点型字面量 |
| CONSTANT\_Long\_info | 5 | 长整型字面量 |
| CONSTANT\_Double\_info | 6 | 双精度浮点型字面量 |
| CONSTANT\_Class\_info | 7 | 类或接口的符号引用 |
| CONSTANT\_String\_info | 8 | 字符串类型字面量 |
| CONSTANT\_Fieldref\_info | 9 | 字段的符号引用 |
| CONSTANT\_Methodref\_info | 10 | 类中方法的符号引用 |
| CONSTANT\_InterfaceMethodref\_info | 11 | 接口中方法的符号引用 |
| CONSTANT\_NameAndType\_info | 12 | 字段或方法的部分符号引用 |
| CONSTANT\_MethodHandle\_info | 15 | 表示方法句柄 |
| CONSTANT\_MethodType\_info | 16 | 表示方法类型 |
| CONSTANT\_Dynamic\_info | 17 | 表示一个动态计算常量 |
| CONSTANT\_InvokeDynamic\_info | 18 | 表示一个动态方法调用点 |
| CONSTANT\_Module\_info | 19 | 表示一个模块 |
| CONSTANT\_Package\_info | 20 | 表示一个模块中开放或者导出的包 |


### 访问标志


在常量池结束之后, 紧接着的2个字节代表 **访问标志** , 用于识别一些类或者接口层次的访问信息, 包括: 这个Class是类还是接口; 是否为 public 或者abstract; 如果是类的话, 是否被声明为 final




| 标志名称 | 标志值 | 含义 |
| --- | --- | --- |
| ACC\_PUBLIC | 0x0001 | 是否为public |
| ACC\_FINAL | 0x0010 | 是否为final |
| ACC\_SUPER | 0x0020 | 是否使用invokespecial字节码指令的新语义 |
| ACC\_INTERFACE | 0x0200 | 是否是一个接口 |
| ACC\_ABSTRACT | 0x0400 | 是否为abstract |
| ACC\_SYNTHETIC | 0x1000 | 标识这个类并非由用户代码产生的 |
| ACC\_ANNOTATION | 0x2000 | 标识这是一个注解 |
| ACC\_ENUM | 0x4000 | 标识这是一个枚举 |
| ACC\_MODULE | 0x8000 | 标识这是一个模块 |


### 类索引, 父类索引和接口索引集合


类索引, 父类索引和接口索引都按顺序排列在访问标志之后, 类索引和父类索引用两个u2类型的索引值表示, 它们各自指向一个类型为CONSTANT\_Class\_info的类描述符常量, 通过CONSTANT\_Class\_info类型的常量中的索引值可以找到定义在 CONSTANT\_Utf8\_info类型的常量中的全限定名字符串



u2             this_class;//当前类
u2             super_class;//父类
u2             interfaces_count;//接口数量
u2             interfaces[interfaces_count];//一个类可以实现多个接口

类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,由于 Java 语言的单继承,所以父类索引只有一个,除了 `java.lang.Object` 之外,所有的 Java 类都有父类,因此除了 `java.lang.Object` 外,所有 Java 类的父类索引都不为 0。


### 字段表集合


字段表用于描述接口或类中声明的变量. 字段包括类级变量以及实例变量, 但不包括在方法内部声明的局部变量



u2             fields_count;//字段数量
field_info     fields[fields_count];//一个类会可以有个字段

字段表结构



field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 atributes_count;
attribute_info attributes[attributes_count];
}


* **access\_flags** : 字段的作用域 (`public` , `private` , `protected` 修饰符), 是实例变量还是类变量, 可否被序列化, 可变性( `final` 修饰 ) , 可见性(`volatile`)
* **name\_index** : 对常量池的引用, 表示的字段的名称
* **descriptor\_index** : 对常量池的引用, 标识字段和方法的描述符
* **attributes\_count** : 一个字段还会拥有一些额外的属性, attributes\_count 存放属性的个数
* **attributes[attributes\_count]** : 存放具体属性具体内容


上述这些信息中, 各个修饰符都是布尔值, 要么有某个修饰符, 要么没有, 很适合使用标志位来表示. 而字段叫什么名字, 字段被定义为什么数据类型这些都是无法固定的, 只能引用常量池中常量来描述


### 方法表集合


Class文件存储格式中对于方法的描述和对字段的描述几乎是一模一样的, 方法表的结构如同字段表一样, 依次包括了访问标志, 名称索引, 描述符索引, 属性表集合等



u2             methods_count;//方法数量
method_info    methods[methods_count];//一个类可以有个多个方法

方法表结构



method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}


因为 `volatile` 和 `transient` 修饰符不能修饰方法, 所以方法表的访问标志中没有这两个对应的标志, 但是增加了 `synchronized` , `native` , `abstract` 等关键字修饰方法, 所以也就多了这些关键字对应的标志


### 属性表集合



u2 attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合


与 Class 文件中其他的数据项目要求严格的顺序, 长度, 内容不同, 属性表集合的限制稍微宽松一点, 不再要求各个属性表具有严格的顺序, 并且Java虚拟机规范允许只要不与已有属性名重复, 任何人实现的编译器都可以向属性表中写入自己定义的属性信息, Java虚拟机运行时会忽略掉它不认识的属性




![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)


最全的Linux教程,Linux从入门到精通

======================

1.  **linux从入门到精通(第2版)**

2.  **Linux系统移植**

3.  **Linux驱动开发入门与实战**

4.  **LINUX 系统移植 第2版**

5.  **Linux开源网络全栈详解 从DPDK到OpenFlow**



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)



第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)



**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**

> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值