JVM-class文件完全解析-常量池
在.java文件,讲过javac编译后产生的 .class文件中,头4个字节表示的是魔数,接着魔数后面的第5,6个字节存储的是次版本号,第7,8个字节存储的主板本号.那么再接下来的就是表示常量池入口了.
常量池
可以理解为class文件之中的资源仓库,它是class文件结构中与其他项目关联最多的数据类型,也是占用class文件空间最大的数据项目之一,同时它还是class文件中第一个出现表类型的数据项目.
由于常量池的数量是不固定的,所以在常量池入口需要放置一项u2(即2个字节)类型的数据,代表常量池容量计数值(constant-pool-count)(从1开始,将0表示不引用任何常量).
常量池中主要存放两大类常量:字面量(Literal)和符号引用(Synbolic Reference).
- 字面量:比较接近于Java语言层面的常量概念,如文本字符串,声明为final的常量值.
- 符号引用:包括如下三类常量:
- 类和接口的全限定名(Fully Qualified Name)
- 字段的名称和描述符(Descriptor)
- 方法的名称和描述符
常量池中每一项常量都是一个表(14种表).
| 类型 | 标志 | 描述 |
| 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_MothodType_info | 16 | 标志方法类型 |
| CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
| CONSTANT_InvokeDynamic_info | 18 | 表示一个动态方法调用点 |
注意:在这14种表有一个共同的特点,就是开始的第一位是一个u1类型的标志位(tag,就是上表中的标志这一列),代表当前这个常量属于哪种常量类型.下面分析实例的时候会用到.
下面我们接着上一篇分析的class文件继续往下走.
这张图中,我们继续分析了接着主版本号接下来的几个字节,首先是常量池入口是0x0013,转化为十进制就是19,那么表示的范围就是1~18,因为0用来表示不引用任何常量池了.那么也就是说0x0013之后有18个常量池.我们看紧接着的一个常量池,十六进制0x0a用十进制表示就是10,通过上表的标志列我们可以直到,10对应的那一行就是CONSTANT_Methodref_info类型的表,是类中方法的符号引用.那么知道了是CONSTANT_Methodref_info表,就可以根据CONSTANT_Methodref_info表的结构继续往下分析,一直到分析完18个常量池.在这里就不一一往下分析了,直接通过javap工具来直接查看,也顺便查看我们分析的对不对.
我们从javap的结果看出,常量池的范围就是1~18,然后第一个常量池就是Method,也即CONSTANT_Methodref_info.
JVM-class文件完全解析-常量池的更多相关文章
- 《Java虚拟机原理图解》 1.2.2、Class文件里的常量池具体解释(上)
[last updated:2014/11/27] NO1.常量池在class文件的什么位置? 我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了clas ...
- java基础(八) 深入解析常量池与装拆箱机制
引言 本文将介绍常量池 与 装箱拆箱机制,之所以将两者合在一起介绍,是因为网上不少文章在谈到常量池时,将包装类的缓存机制,java常量池,不加区别地混在一起讨论,更有甚者完全将这两者视为一个整体, ...
- 《Java虚拟机原理图解》 1.2.2、Class文件中的常量池详解(上)
我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了class的文件结构,在class文件中的魔数.副版本号.主版本之后,紧接着就是常量池的数据区域了,如下 ...
- jvm源码解读--04 常量池 常量项的解析CONSTANT_Class_info
接上篇的继续 ConstantPool* constant_pool = ConstantPool::allocate(_loader_data, length, CHECK_(nullHandle) ...
- jvm源码解读--05 常量池 常量项的解析JVM_CONSTANT_Utf8
当index=18的时候JVM_CONSTANT_Utf8 case JVM_CONSTANT_Utf8 : { cfs->guarantee_more(2, CHECK); // utf8_l ...
- jvm源码解读--03 常量池的解析ConstantPool
先看bt栈 (gdb) bt #0 ConstantPool::allocate (loader_data=0x7fe21802e868, length=87, __the_thread__=0x7f ...
- 《Java虚拟机原理图解》 1.2.3、Class文件中的常量池详解(下)
CONSTANT_Fieldref_info, CONSTANT_Name_Type_info) 一般而言,我们在定义类的过程中会定义一些 field 字段,然后会在这个类的其他地方(如方法中)使用到 ...
- 《Java虚拟机原理图解》 1.2.3、Class文件里的常量池具体解释(下)
NO9.类中引用到的field字段在常量池中是如何描写叙述的?(CONSTANT_Fieldref_info, CONSTANT_Name_Type_info) 一般而言.我们在定义类的过程中会定义一 ...
- Class文件内容及常量池
当JVM运行Java程序的时候,它会加载对应的class文件,并提取class文件中的信息存放在JVM开辟出来的方法区内存中.那么这个class文件里面到底有些什么内容呢? 一.class文件内容概述 ...
随机推荐
- Hbase之使用多Get实例返回数据
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hado ...
- html list <==> unformatted list
两者的区别很大不得不擦呢,任何两个东西的差别都很大,不得混淆.---一个有ul/ol的选择,一个没有
- js节点问题
转载 http://dwt1220.blog.51cto.com/1028523/745402 本文出自 “dwt1220” 博客,请务必保留此出处http://dwt1220.blog.51cto. ...
- jmeter笔记2
使用jmeter它来完成最常用的三种类型服务器,即 Web 服务器.数据库服务器和消息中间件,压力测试的方法.步骤以及注意事项. 讲到测试,人们脑海中首先浮现的就是针对软件正确性的测试,即常说的功能测 ...
- 30 个有用的 HTML5 和 CSS3 表单设计
基本上表单是任何一个网站都必须要用到的元素,本文介绍的这 30 个设计方案供你参考,这些方案如果要单独下载完整可运行的文件则需要支付2-5美元的费用. 1. Fresh Forms 2. Pretty ...
- 关于mvc3.0RadioButtonFor的使用
以前本人没有使用过mvc,近期的话公司要求使用mvc进行开发项目,我不得不学习,我在这里分享下Html.RadioButtonFor的使用,例如 @Html.RadioButtonFor(d => ...
- [saiku] 配置spring-security 允许 iframe加载saiku首页
最近提出了一个需求:在一个iframe中展现saiku首页 呵呵,这还不简单. 直接<iframe src="http://localhost:8080/saiku" /&g ...
- 初学java之try-catch-finally语句的实例
/* try - catch语句的例子,模拟向货船上装载集装箱 ,如果货船超重,那么货船认为这是一个异常,将拒绝装载集装箱, 但无论是否发生异常,货船都需要正点起航. */ package st; c ...
- Merge Sorted Array [LeetCode]
Given two sorted integer arrays A and B, merge B into A as one sorted array. Note:You may assume tha ...
- inout
在函数声明时就用inout代替var 这样以后可以在函数内部修改外面的值 类似于C语言的传入指针 func change (inout num:Int) { num = 10 } var a = 2 ...
