大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
字符串常量池详解
文章所涉及的资料来自互联网整理和个人总结,仅作为个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!
概述
在JVM中,为了减少字符串对象的重复创建,维护了一块特殊的内存空间,这块内存空间就被称为字符串常量池。
在JDK1.6及之前,字符串常量池存放在方法区中。到JDK1.7之后,就从方法区中移除了,而存放在堆中。一下是《深入理解虚Java虚拟机》第二版原文:
对于HotSpot 虚拟机,根据官方发布的路线图信息,现在也有放弃永久代并逐步改为采用Native Memory来实现方法区的规划了,在目前已经发布的JDK1.7 的HotSpot中,已经把原本放在永久代的字符串常量池移出。
根据查阅的资料显示在JDK1.7以后的版本中字符串常量池移到堆内存区域;同时在jdk1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域
创建字符串对象的两种方法
-
直接使用双引号声明出来的
String
对象会直接储存在常量池中。String s1 = "abc"
-
使用new方法创建出来的
String
对象,可以使用String
提供的intern
方法。intern 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中
String s2 = new String("xyz");
public class Test1{
public class void main(String[] args){
String s1 = "abc";
String s2 = "abc";
System.out.println(s1);//abc
System.out.println(s1 == s2);//true
char[] charArray = {
'a','b','c'};
String s3 = new String(charArray);
System.out.println(s3);//abc
System.out.println(s1 == s3);//false
}
}
从结果看,两个布尔值的结果不相同,虽然两个输出两个字符串的结果相同,都为abc
,但比较两者时则不同,这是因为引用类型比较时,比较的是其地址值;不同于基本数据类型比较的是其数据值。
采用直接创建String
类型对象的方法创建对象时,JVM首先会去字符串常量池中查找是否存在”abc” 这个对象,如果不存在,则在字符串常量池中创建”abc“这个对象,然后将池中”abc“对象的引用地址返回给对象s1
,这样s1
的地址就在常量池中;
如果存在,则不创建任何对象,直接将存在的“abc”的地址返回给对象s2。这就是为什么s1等于s2的原因。
而通过new
方法创建的String
对象,其创建的字符串是放在堆当中的,将堆当中的字符串地址返回赋值给s3
,s1和s3的存放地址不相同,一个在字符串常量池中,一个在堆当中,字符串常量池外,因此返回的值是false。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/164774.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...