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对象字面量相同时,需要进行区分两者!

相关推荐
Re_zero2 小时前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记2 小时前
Spring Boot条件注解详解
java·spring boot
程序员清风20 小时前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5511 天前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊1 天前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing1 天前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠2 天前
各版本JDK对比:JDK 25 特性详解
java
用户8307196840822 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide2 天前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
IT探险家2 天前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java