当前位置:网络安全 > Java常量池

Java常量池

  • 发布:2023-09-23 12:39

最近在看Java虚拟机,对于常量池又有了新的理解,以前学习的时候就在各个博客上学习过,再结合最近的学习发现有些博客上对于常量池还是有一定的理解偏差,今天写出来和大家分享一下。
1、Java常量池技术,讲的是位于jvm中方法区的常量池,它主要作用是存储一些final的量,和编译期就确定下的量,还有就是与Java类字节码文件相关的一些数据。在这里我们一般只讨论两种类型。
1)基本数据类型
2)String类型
2、常量池技术的具体实现是什么样的呢?
在Java中如果定义两个int类型的变量,其值都为127;

int a = 127;
int b = 127;

如上面代码实现,在jvm中怎么样分配内存的呢?
在创建a变量时首先查看其值得范围,是否在-128~127之间,如果在则到常量池中查找是否有127,如果有则返回引用,如果没有在添加,并返回其引用。在创建b时执行同样的过程,这样就减少了内存的分配。

3、首先我们讲解基本类型,在八种基本数据类型中,实现常量池技术的只有:Byte、Integer、Short、Character、Long、Boolean而两种浮点类型没有实现。但是在Integer、Short、Character、Long中虽然实现了但是其数值要求必须是在-128~127,其常量池技术的实现参看步骤2.
4、String类型常量池技术的实现
因为String类型的特殊性,即既可以当做对象处理,也可以做基本类型处理,所以,在实现上有些特殊。如下讲解:

String str1 = "hello";
String str2 = "he"+"llo";

如上代码实现的字符串的创建,此时将String类型当做基本类型处理,在第二行代码中,Java虚拟机在编译期处理时,首先将其进行连接处理后,再进行常量池技术的处理。所以上面的str1 == str2是true的。

String str3 =new String("hello");

这行代码在jvm中首先是在堆上申请了存储空间,再在常量池中查看是否存在“hello”,如果存在则返回引用到堆中申请的存储空间,如果没有则添加,并返回引用到存储空间,而str3中存储的是堆内存的引用。
如果要想这两种方式实现str1 == str3,是true的,在String 中有intern方法。其作用是获得字符串在常量池中的引用并返回;通过如下方法:

str3 = str3.intern();

这时再判断就成立了;
因为string是不可变的,所以在常量池中存在的字符串是不可修改的,即使如下:

String str4 = str3 +"world";

则在常量池中仍然存在”hello” ,并且会产生两个新的字符串常量“world”“helloworld”,对比上面的字符串连接处理,深刻理解JVM中对字符串的处理。
如上是我个人对常量池的理解,如有不对的地方欢迎留言。

相关文章

热门推荐