Java-常量池

2023-11-13

Java-常量池

       常量池是类文件中最复杂的数据结构。对于JVM字节码来说,如果操作数是很常用的数字,比如 0,这些操作数是内嵌到字节码中的。如果是字符串常量和较大的整数等,Class文件则会把这些操作数存储到常量池中,当使用这些操作数时,会根据常量池的索引位置来查找。

       常量池可以比喻为class文件里的资源仓库,它是Class文件结构中与其他项目关联最多的数据,通常也是占用Class文件空间最大的数据项目之一,另外,他还是在Class文件中第一个出现的表类型数据项目。

常量池的结构:
struct {
u2                constant_pool_count;
cp_info         constant_pool[ constant_pool_count-1 ];
}

(1) 常量池大小(cp_info_count): 常量池是Class文件中第一个出现的变长结构。既然是池就有大小,所以在常量池的入口需要放置一项u2(两个字节)类型的数据,代表常量池容量计数值。与Java中语言习惯不同,这容量是从1开始的而不是从0开始的。0属于保留索引,可供特殊情况使用。(Class文件只有常量池的容量计数是从1开始的,对于其他集合类型,包括接口索引集合,字段表集合,方法表集合等的容量计数都与一般习惯相同,是从0开始的)。

(2)常量池项(cp_info)集合: 最多包含 n-1 个元素。因为long和double类型的常量会占用两个索引位置,如果常量池包含了这两种类型的元素,实际的常量池的元素个数比 n-1 要小。

Java虚拟机目前一共定义了14中常量项tag类型,如下表:

类型 tag(标志) 描述
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 表示一个动态计算常量

1、 boolean,byte,short ,char 和 float 类型

Java语言规范定义了boolean,byte,short 和 char 类型的变量在常量池中都会被当作 int 来处理。int 和 float 都是用 4 个字节来表示具体的数值常量。

接下来测试一下:( 此处在 IDEA里面下载插件jclassbil之后,点击View——>Show Bytecode With Jclassbil 可查看 )

1.1 Boolean

public class HelloWorld {
    public final boolean bool = true;
}

在这里插入图片描述

1.2 Byte

public class HelloWorld {
    public final byte aByte = Byte.MAX_VALUE;
}

在这里插入图片描述
对于short,char, int 和 float 同样可以测试,此处不再赘述。

2、long 和 double 类型

long 和 double 类型的常量都用8个字节表示具体的常量数值( 分为 high_bytes 和 low_bytes )。接下来测试一下:

2.1 long

public class HelloWorld {
    public final long aLong = Long.MAX_VALUE;
}

在这里插入图片描述

2.2 double

public class HelloWorld {
    public final double aDouble = Double.MAX_VALUE;
}

在这里插入图片描述
可见CONSTANT_Long_info 和 CONSTANT_Double_info 都是占用两个常量池位置(例子中的[09] 和 [10])。

3、CONSTANT_Utf8_info

(1) 对于传统的ASCII编码字符 ( 0x0001~0x007F ),UTF-8 用一个字节来表示,如下所示。
0000 0001 ~ 0000 007F --> 0xxxxxxx
因此英文字母的ASCII编码和UTF-8编码的结果一样。

(2) 对于0080 ~ 07FF 范围的字符,UTF-8用2个字节来表示,如下图所示。
0000 0080 ~ 0000 07FF --> 110xxxxx 10xxxxxx
程序遇到这种字符的时候,会把第一个字节的110和第二个字节的10去掉,再把剩下的bit组成新的两字节数据。

(3) 对于 0000 0800 ~ 0000 FFFF 范围的字符,UTF-8 用 3 个字节表示,如下所示。
0000 0800 ~ 0000 FFFF --> 1110xxxx 10xxxxxx 10xxxxxx
程序遇到这种字符的时候,会把第一个字节的1110,第二个字节和第三字节的10去掉,再把剩下的bit组成新的3字节数据。

(4) 对于 0001 0000 ~ 0010 FFFF 范围的字符,UTF-8 用4个字节表示,如下所示。
0001 0000-0010 FFFF --> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
程序遇到这种字符的时候,会把第一个字节的1110以及第二个,第三,第四字节中的10去掉,再把剩下的bit组成新的4字节数据。

4、CONSTANT_String_info

CONSTANT_String_info用来表示java.lang.String类型的常量对象。
CONSTANT_Utf8_info 存储了字符串真正的内容,而CONSTANT_String_info并不包括字符串的内容,仅仅包含一个指向常量池中的CONSTANT_Utf8_info常量类型的索引。

public class HelloWorld {
    public final String str = "Hello JVM";
}

在这里插入图片描述
在这里插入图片描述
可看到[07]处是CONSTANT_String_info,存储了一个索引,指向[08],[08]处是CONSTANT_Utf8_info, 存储的才是字符串 Hello JVM

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java-常量池 的相关文章

随机推荐

  • 3_服务容错_保护断路器_@EnableCircuitBreaker和引入@SpringCloudApplication

    前言 前面做了一个简单的服务 注册 服务发现 服务提供者和消费者的项目 现在我们还是准备之前的项目代码 1 服务容错保护 准备的项目工程 1 服务注册中心 端口为1111 2 服务提供者 端口为8080 8081 3 服务消费者 端口为90
  • 华为OD机试真题- 天然蓄水库【2023】【JAVA、Python、C++】

    题目描述 描述 公元2919年 人类终于发现了一颗宜居星球 X星 现想在X星一片连绵起伏的山脉间建一个天热蓄水库 如何选取水库边界 使蓄水量最大 要求 山脉用正整数数组s表示 每个元素代表山脉的高度 选取山脉上两个点作为蓄水库的边界 则边界
  • Springboot连接FISCO-BCOS链

    依赖 FISCO BOCS 2 5 0 JAVA 1 8 Spring Boot 2 0 2 官方文档 前期准备 部署FISCO BOCS 2 5 0 引入SDK
  • ue 清理缓存_mpvue应用之组件数据缓存清理

    题图 被mpvue周期搞疯的你 之前介绍过美团外卖C端 H5 小程序页面大量基于mpvue框架的能力 使用Vue组件打通了原生小程序页面和H5页面的隔阂 再结合小程序自带的原生组件功能 就构成了整个外卖跨端应用的终端部分架构 但是随着页面规
  • 唐诗三百首出现最多的字是什么?大数据分析告诉你

    一个人要是长时间一直做一件事 思维容易固化 就像那些从太空回来的宇航员 吃饭时容易丢开拿在手里的勺子 当勺子掉在地上时 哦 我已经回到地球了 所以 适当尝试新鲜事物 既是对大脑的放松 也是开阔思路的好机会 好方法 那这次 博主尝试的新事物是
  • 腾讯面经 集合

    腾讯机器学习复试 gbtd和xgboost区别和优缺点 XGBoost是GBDT一个工程化的实现 第一 GBDT将目标函数泰勒展开到一阶 而xgboost将目标函数泰勒展开到了二阶 使用泰勒展开到二阶的原因 统一损失函数求导的形式以支持自定
  • CFLAGS详解

    Makefile选项CFLAGS LDFLAGS LIBS CFLAGS 表示用于 C 编译器的选项 CXXFLAGS 表示用于 C 编译器的选项 这两个变量实际上涵盖了编译和汇编两个步骤 CFLAGS 指定头文件 h文件 的路径 如 CF
  • XXXXXXXXXXXXX

    Netflix主机性能监视工具Vector http www chinaz com web 2015 0414 398451 shtml 云雀科技是总部位于西雅图的新兴的云服务公司 利用业界 最新技术打造下一代具有高密度动态计算能力的云平台
  • 初学网络安全不可不知的:10款开源安全工具

    随着互联网的不断发展 安全问题也越来越受到企业的重视 但安全问题往往需要大量资金的投入 例如聘请安全工程师 产品研发 测试等流程 这对于那些原本就资金紧缺的企业而言 是绝对无法接受的 因此 为了减少在这方面的资金投入 许多安全人员都会选择使
  • keyframes介绍与调用动画方法

    keyframes介绍 keyframes changecolor 0 background red 50 background red 100 background green 在一个 keyframes 中的样式规则可以由多个百分比构成
  • APB总线详解及手撕代码

    本文的参考资料为官方文档AMBA 3 APB Protocol specification 文档下载地址 https pan baidu com s 1Vsj4RdyCLan6jE quAsEuw pwd w5bi 提取码 w5bi APB
  • Spring Bean如何保证并发安全

    1 可以设置Bean的作用域为原型 这样每次从容器中获取到的Bean就是一个新的实例 避免了多线程共享同一个对象实例的问题 2 不改变Bean作用域的情况下 可以避免在Bean中存可变状态的声明 尽量使用局部变量或使用线程安全的数据结构 3
  • Visual Station 2022的头文件包含目录设置的区别

    1 前言 对vs的包含头文件的组织 你困惑吗 困惑 有点困惑 BullS 在没喊出 BullSHI 之前 我先查了很多博客 结果 有的说 VC Directories gt Include Directories 适用于当前项目 C C g
  • BUUCTF [ACTF2020 新生赛]Exec

    1 刚打开的时候如图所示 先随便用一个地址127 0 0 1 2 然后查下目录127 0 0 1 ls ls看文件目录 发现flag 直接抓127 0 0 1 cat flag 拿到flag flag fdc896b1 e032 4e87
  • 如何训练自己的tokenizer

    训练自己的 tokenizer 通常需要以下几个步骤 准备数据 选择一些文本数据作为训练数据 并将其按照一定的方式拆分成若干个 token 例如将句子按照空格拆分成单词 选择模型 选择一种适合你的任务的模型 例如基于字符的模型或基于单词的模
  • electron 生成 arm64 的包

    vue electron https blog csdn net qq1195566313 article details 131713875 打包配置修改如下 electronBuilder build config appId com
  • 目标检测-YOLOv7代码及训练

    目录 论文及代码下载 代码结构 代码学习 1 train py 1 1 参数 1 2 Resume 训练中断后继续训练 1 3 Train 训练 2 yolov7 yaml 2 1 parameters and anchors 2 2 网络
  • 阿姆达尔定律

    原文地址 作者 Jakob Jenkov 译者 张坤 阿姆达尔定律可以用来计算处理器平行运算之后效率提升的能力 阿姆达尔定律因Gene Amdal 在1967年提出这个定律而得名 绝大多数使用并行或并发系统的开发者有一种并发或并行可能会带来
  • HDFS RBF的Connection管理

    文章目录 前言 Connection管理的权衡问题 RBF的Connection管理 细粒度的Connection Pool划分 Connection的创建 Connection的清理 参考资料 前言 为了解决HDFS Federation
  • Java-常量池

    Java 常量池 常量池是类文件中最复杂的数据结构 对于JVM字节码来说 如果操作数是很常用的数字 比如 0 这些操作数是内嵌到字节码中的 如果是字符串常量和较大的整数等 Class文件则会把这些操作数存储到常量池中 当使用这些操作数时 会