Java常量池理解

article/2025/9/23 22:53:11

Java常量池理解

常量池分为两种:静态常量池和运行时常量池。

静态常量池

每个类在编译之后都会生成class文件,而class文件中就包含有静态常量池,分析class文件,如下图所示:
这里写图片描述

由于常量池中的常量的数量不是固定的,所以常量池的入口需要放置一项u2类型的数据,代表常量池的容量计数值。这里的常量池容量计数值是从1开始的。如图常量池的容量:0x001d(29)。所以共有29个常量。

运行时常量池

静态常量池编译完成之后就会保存再class文件中,当class文件中类被加载到内存中的时候,静态常量池中的常量最终都会存放到运行时常量池中,我们最终使用的都是运行时常量池的常量。
在JDK6.0及之前版本,字符串常量池是放在Perm Gen区(也就是方法区)中;
在JDK7.0版本,字符串常量池被移到了堆中了。

静态常量池和运行时常量池的区别?

看名字基本上就可以猜出来,静态常量池中的常量是不能够改变的,编译完成之后就无法改变了,但是运行时常量池却可以在运行时动态添加,如使用String的intern()方法,这个方法就可以把String中的字符串字面量添加到常量池中去。

常量池的好处

  1. 空间考虑
    相同的常量只占用一块内存
  2. 时间考虑
    使用==判断字符串是否相等的时候,不用像equals()方法样去比较内容,而是直接比较地址就可以了,因为常量池中保证了不同的常量的地址一定不一样。

字符串常量的理解

案例1

public class test {
public static void main(String[] args) {
String s1="abc1";//此处是数字1
String s2="abc"+1;
System.out.println(s1==s2);// 第一次比较
String s3="ab";
String s4="c";
String s5="abc";
String s6=s3+s4;
System.out.println(s5==s6);// 第二次比较
}
}

结果:
true
false
“abc”+1都是字面量,字面量在编译生成class文件时,编译器会将他们两优化到一起,放到静态常量池中去,既然已经放到静态常量池中去了,那么运行时常量池必定会存在,而s2拿的时候,运行时常量池就已经存在了abc1,所以s1和s2拿到到字符串常量是相同的。
而后面s3+s4都是字符串对象的拼接而不是字面量,所以在编译的时候不会放到常量池中去。

案例2

public class test {
public static final String s1="abc";
public static final String s2="def";
public static void main(String[] args) {
String s3=s1+s2;
String s4="abcdef";
System.out.println(s3==s4);
}
}

结果:
true

从这里可以看出,只要是引用在编译期能够直接指向有且仅有一个常量时,这个时候引用就是字符串常量

案例3

public class test {
public static final String s1;
public static final String s2;
static{
s1="abc";
s2="def";
}
public static void main(String[] args) {
String s3=s1+s2;
String s4="abcdef";
System.out.println(s3==s4);
}
}

结果:
false

这种情况和上面情况不同,因为static代码块是在运行时才会执行的,所以在编译时s1,s2虽然是final修饰,但是没有被赋值,所以仍然还是变量。

基本类型数据都有常量池吗?

不是的,Float和Double就没有实现常量池,Integer是实现了常量池的。但是Integer和字符串常量池有点区别。区别如下:

public class test {
public static void main(String[] args) {
Integer i1=10;
Integer i2=10;
Integer i3=20;
Integer i11=new Integer(10);
Integer i22=new Integer(10);
Integer i33=new Integer(20);
System.out.println(i1==i2);
System.out.println(i1==i11);
System.out.println(i11==i22);
System.out.println(i3==(i1+i2));
System.out.println(i3==(i11+i22));
System.out.println(i33==(i1+i2));
System.out.println(i33==(i11+i22));
}
}

结果:
true
false
false
true
true
true
true
其他的都好理解,主要是i33==(i1+i2),这里要特别注意:
1. 只要Integer进行了运算符运算就是进行自动拆箱操作,也就是说将包装类拆成字面量
2. 只要是一个数值字面量和一个Integer进行表达式运算,则Integer也会自动拆箱
所以这里实际上是20==20的恒等式。

这里提到的自动装箱和自动拆箱的概念大家可以看一下我的另外一篇blog。


http://chatgpt.dhexx.cn/article/Y4dTmbml.shtml

相关文章

Java 常量池详解(二)class文件常量池 和 Java 常量池详解(三)class运行时常量池

Java 常量池详解(一)字符串常量池 2.class文件常量池(class constant pool) 产生时机:当java文件被编译成class文件之后,就会生成class常量池,跟jvm 无关系 常量池主要存放两大类常量&#xff…

java 查看类常量池_Java中常量以及常量池

1、举例说明 变量 常量 字面量 1 int a=10;2 float b=1.234f;3 String c="abc";4 final long d=10L; a,b,c为变量,d为常量 两者都是左值;10,1.234f,"abc",10L都是字面量; 2、常量池: 常量池专门用来用来存放常量的内存区域,常量池分为:静态常量池…

一文解析Java常量池、静态常量池、运行时常量池和字符串常量池的区别与联系

Java常量池关系图 Java常量池 Java常量池是Java编译器在编译Java源代码时,为了优化性能和节省空间所创建的一种常量缓存机制。它包含了所有的基本数据类型、字符串常量、符号引用等常量,这些常量都是在编译期被确定下来的,并被存储在.class文…

java常量池总结

java常量池 1.class常量池2.运行时常量池3.基本类型包装类常量池4.字符串常量池 1.class常量池 在JAVA中,Java类(.java)文件被编译后就会形成一份class文件;class文件中除了包含类的版本、字段、方法、接口等描述信息外&#xff…

java号码池_Java常量池详解

jvm虚拟内存分布图: 程序计数器:JVM执行程序的流水线。 本地方法栈:JVM调用操作系统方法所使用的栈。 虚拟机栈:JVM执行Java代码所使用的栈。 方法区:存放一些常量、静态变量、类信息等;可以理解为class文件…

java常量池在哪里_【Java基础】Java常量池在哪里? - 收获啦

1.java常量池的介绍 java中的常量池,通常指的是运行时常量池,它是方法区的一部分,一个jvm实例只有一个运行常量池,各线程间共享该运行常量池。 java常量池简介:java常量池中保存了一份在编译期间就已确定的数据。它里面…

java静态池_java 常量池静态变量详解

Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。 所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分…

java常量池在哪里_Java常量池详细说明

java常量池技术 java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复创建相等变量时节省了很多时间。常量池其实也就是一个内存空间&#x…

java中常量池存的是什么_Java中常量池是什么?Java常量池的介绍

本篇文章给大家带来的内容是关于Java中常量池是什么?Java常量池的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 Java当中的常量池 在Java虚拟机jvm中,内存分布为:虚拟机堆,程序计数器,本地方法栈,虚拟机栈,方法区。 程序计数器是jvm执行程序的…

java long常量池_Java-常量池

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

Java常量池原理以及垃圾回收

Java常量池 常量池:用于存放编译期间生成的各种字面量和符号引用 字面量:由字母数字等构成的字符串或数值常量,如int a 1中 1就是字面量 符号引用:编译原理中的概念;是相对直接引用来说的,主要包括三类常…

Java 常量池详解(一)字符串常量池

在Java的内存分配中,总共3种常量池: Java 常量池详解(二)class文件常量池 和 Java 常量池详解(三)class运行时常量池 1.字符串常量池(String Constant Pool) 在JDK1.7之前运行时常量池逻辑包含…

Java常量池储存什么_JAVA常量池中存储的常量是什么

展开全部 我当初也存在这样一个疑问,下面我把e69da5e887aa3231313335323631343130323136353331333262356165当初所搜集的一些资料以及自己的理解贴出来给你看看(比较多,需要耐心点看,呵呵): 理解Java常量池 JVM运行时数据区的内存…

深度剖析Java常量池

Class常量池 class常量池可以理解为是Class文件中的资源仓库。Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池(constant pool table),用于存放编译期生成的各种字面量和符号引用。 一个Class文件的16进制大体结构如…

Java常量池

Java常量池 一.相关知识 1.何为常量 第一种常量:是一个值,我们将这个值本身称为常量。比如: 整型常量:1024 实型常量:1.024 字符常量:g c w 字符串常量:"gcw" 逻辑常量:t…

Java 常量池

常量池分为 Class 常量池常量池、运行时常量池、字符串常量池。 1、 Class 常量池常量池(静态常量池) Java 文件被编译成 Class 文件,Class 文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项就是 Class 常量池&am…

JAVA常量池,一篇文章就足够入门了。(含图解)

前言 一直在《深入理解JVM》对常量池只有一个浅薄的了解,之前也遇到过这种题目,今天还是要挑出来进行一次全方位的了解。 常量池分类 常量池大体可以分为:静态常量池,运行时常量池。 静态常量池 存在于class文件中&#xff0c…

基于Elman神经网络的刀具剩余使用寿命预测(初学者+matlab代码实现)

1.Elman介绍 Elman神经网络是 J. L. Elman于1990年首先针对语音处理问题而提出来的,是一种典型的局部回归网络( global feed forward local recurrent)。Elman网络可以看作是一个具有局部记忆单元和局部反馈连接的递归神经网络 它的主要结构是前馈连接, 包括输入层、…

通过模拟退火改进的Elman神经网络(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 神经网络是一个庞大的体系和概念,根据处理信息的不同方式来区分不同的network。比如根据处理信息结果的传递方向&am…

基于遗传算法优化的Elman神经网络数据预测-附代码

基于遗传算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于遗传算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于遗传优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要:针…