Java字节码文件常量池索引两个问题

先结合字节码文件分析一下字段是怎么在常量池中存储的:

以String类型为例:

在一个类中定义两个字段:

复制代码
public static final String a1 = "我爱北京天安门";
public static final String a2 = "我爱北京天安门";

在字节码文件中,在字段表中会出现两个字段分别为a1和a2,在a1中会存储两个索引,一个是指向变量名a1的索引,是一个字面量索引,CONSTANT_Utf8_info索引;一个是指向String对象"我爱北京天安门"的索引,是一个字符串索引,CONSTANT_String_info索引。然后点击String对象的CONSTANT_String_info索引,会指向一个字面量索引CONSTANT_Utf8_info索引,内容是"我爱北京天安门"。归根结底变量名和字符串对象都是用字面量来存储的,只不过:变量名直接指向字面量索引,字符串对象先指向字符串索引,再指向字面量索引。

那么问题来了?

  1. 为什么字符串要绕一下,为什么不直接指向字面量索引呢?

    这是因为在java中有一个字符串常量池,在运行时需要将String添加在字符串常量池中去,字符串对象先指向字符串索引,可以由此来判断改变量是不是String;如果字符串对象直接指向字面量,无法通过字面量来判断该变量是不是String 。

    一句话因为有字符串常量池!

  2. 那既然String对象需要先指向CONSTANT_String_info索引,为什么CONSTANT_String_info索引存储的是CONSTANT_Utf8_info索引,而不直接存储字符串字面量呢?

    定义以下三个字段:

    复制代码
    public static final String a1 = "abc";
    public static final String a2 = "abc";
    public static final String abc = "abc";

    这三个字段是怎么在字节码文件中存储的呢?

    字段表中有三个字段:a1、a2、abc,a1中有两个索引,变量名索引CONSTANT_Utf8_info,假设该索引值为4,直接指向"a1"字面量;String对象存储的是CONSTANT_String_info索引,该字符串索引指向字面量索引CONSTANT_Utf8_info,假设该索引值为10,该索引指向的是"abc"。a1和a2类似。假设a2的变量名索引CONSTANT_Utf8_info的值为6,其String对象存储的是CONSTANT_String_info索引,该索引指向的是CONSTANT_Utf8_info索引,值为10,与a1一致。

    对于a3,也有两个索引,变量名存储的字面量索引CONSTANT_Utf8_info的值为10,String对象存储的是字符串索引,该索引指向字面量索引,值为10。

    这样的话直接就可以进一步节省空间。可以节省变量名存储的空间。

    如果按照问题表述的,String对象需要存储一个字符串索引CONSTANT_String_info,那么CONSTANT_String_info索引直接存储字面量而不是指向一个字面量索引。在这种情况下,字符串索引存储的是字面量"abc",那么对于变量名来说,为节省空间而让变量名存储CONSTANT_String_info索引,因为这个索引里面存储的是字面量"abc"。这样的话变量名就不是一个字面量而是一个字符串对象了,显然是混乱的,是不可以的。因为字符串常量池里不仅存储字符串常量还有变量名了。

    一句话,变量名字面量与String对象字面量相同时,需要进行区分两者!

相关推荐
侠客行03174 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪5 小时前
深入浅出LangChain4J
java·langchain·llm
老毛肚6 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎7 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
Yvonne爱编码7 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚7 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂7 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
fuquxiaoguang7 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
琹箐7 小时前
最大堆和最小堆 实现思路
java·开发语言·算法
__WanG7 小时前
JavaTuples 库分析
java