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

相关推荐
期待のcode2 小时前
Java的抽象类和接口
java·开发语言
while(1){yan}2 小时前
SpringDI
java·jvm·spring·java-ee
陈平安安2 小时前
设计一个秒杀功能
java·数据库·sql
TAEHENGV2 小时前
基本设置模块 Cordova 与 OpenHarmony 混合开发实战
android·java·数据库
千寻技术帮2 小时前
10422_基于Springboot的教务管理系统
java·spring boot·后端·vue·教务管理
milanleon2 小时前
使用Spring Security进行登录认证
java·前端·spring
毕设源码-朱学姐2 小时前
【开题答辩全过程】以 三叶草中石油信息管理系统的设计与实现为例,包含答辩的问题和答案
java·eclipse
期待のcode3 小时前
@RequestBody的伪表单提交场景
java·前端·vue.js·后端