Java字符串常量池及字符串判等解析
一、理解“==”的含义
“==”常用于两个对象的判等操作,在Java中,“==”主要有以下两种用法:
1、基础数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样;
2、引用数据类型:比较的是两个引用对象指向的内存地址是否相同。
二、字符串常量池
Java中字符串对象主要有两种创建方式,第一种是通过”字面量“赋值,例如:String str="HWY";第二种是通过new关键字创建新对象,
例如String str=new String("HWY");这两种创建String对象有什么区别呢?
要讨论这个问题,首先要明白JVM运行时数据区和字符串常量池(String Pool)

方法区:存储类信息、常量、静态变量,全局共享。
堆区:存放对象和数组,全局共享。
栈区:存放基本数据类型、对象的引用,线程私有。
创建字符串对象主要与方法区、堆区和栈区有关,最相关的是字符串池(String Pool),其位置在jdk1.7之后移动到堆中。
这样我们再回到之前的问题,通过”字面量“赋值,例如:String str="HWY"创建字符串对象时,会在字符串常量池中创建“HWY”的对象,并
存放一个它的引用。此时类并没有加载完成,main方法中还没有创建str,当main方法执行到String str="HWY"时,虚拟机会去字符串池中找是否
有equals(“HWY”)的String,然后把在字符串池中“HWY”的引用复制给str。
当通过new关键字创建新对象,例如String str=new String("HWY")时,无论字符串常量池中是否有equals(“HWY”)的String,都会在堆中开辟一
块新的内存地址,存放一个字符串对象“HWY”,并在常量池中存放该对象的引用(如果发现常量池中已经有了字符串常量“HWY”,就不会再去创建),此时str指向的是堆
中字符串对象的地址。
三、字符串判等解析
了解完两种不同方式创建字符串对象的区别之后,可以看一下以下几个例子:
例1:

输出结果为:

这是比较常见的字符串比较问题,输出结果为false。解析:String s1="HHH",会在字符串常量池中存放一个内容为“HHH”的String对象的引用,并将该引用赋值给s1,
new关键字在堆中创建了一个新的字符串对象,s2指向的该字符串对象在堆中的地址,s2与s1指向的是不同的地址,因而输出false。
例2:

输出结果为:

解析:对于直接做+运算的两个字符串(字面量)对象,并不会放入字符串常量池中,而是直接把运算后的结果放入字符串常量池中
(String s 1= "HE"+ "LLO", 会直接生成字面量为“HELLO"字符串对象 ,s1指向的字符串常量池中“HELLO”的引用, 此时s1==s5为true,
String s4=s2+s3;这句被Java编译器做了优化, 实际上使用StringBuilder调用append方法拼接字符串,再调用toString方法返回String对象实现的,
本质上也是在堆中开辟了新的内存空间,此时s4指向的是堆中新创建的字符串对象地址,因而s1==s4为false。
例3:

输出结果为:

解析:这里涉及到intern()方法的使用,当调用 intern 方法时,如果字符串常量池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),
则返回池中的字符串的引用。否则,将此 String 对象添加到池中,将堆中String对象的引用复制给字符串常量池中,并返回此 String 对象的引用(堆中)。
当s2调用intern()方法时,字符串常量池中已经存在“HWY”字符串,因而直接返回字符串常量池该字符串的引用,所以s2.intern()==s1为true;
对于String s3=new String("中南")+new String("大学");此时会在堆中创建3个对象“中南”、“大学”、“中南大学”,而在字符串常量池中只有“中南”、“大学”两个字符串的引用,
因为我没有明确new("中南大学"),所以在字符串常量池中并没有“中南大学”字符串的引用,此时s3调用intern()方法会将堆中“中南大学”字符串对象的地址复制到字符串
常量池中,然后返回堆中“中南大学”的地址,所以此时s4、s3、s3.intern()的引用地址都相同。
以上内容就是关于Java字符串常量池及字符串判等的总结。
Java字符串常量池及字符串判等解析的更多相关文章
- java——字符串常量池、字符串函数以及static关键字的使用、数组的一些操作函数、math函数
字符串常量池: 字符串比较函数: 字符串常用方法: 字符串截取函数: 字符串截取函数: static关键字使用: 要调用类中的static类型的变量的时候,可以用"类名.变量名&quo ...
- 【转】Error,java对常量池来说字符串xxx的UTF8表示过长的解决及其理解
做项目,客户端这里自己模拟json数据时,一时没忍住搞得json字符串太长了(idea上大概有600多行吧),这个问题就蹦出来了.老方法直接google.百度然后看到一堆有关String 字符串常量池 ...
- Java中的字符串常量池
ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...
- 转载:Java中的字符串常量池详细介绍
引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...
- java字符串常量池——字符串==比较的一个误区
转自:https://blog.csdn.net/wxz980927155/article/details/81712342 起因 再一次js的json对象的比较中,发现相同内容的json对象使用 ...
- Java中的字符串常量池和JVM运行时数据区的相关概念
什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...
- Java中的字符串常量池,栈和堆的概念
问题:String str = new String(“abc”),“abc”在内存中是怎么分配的? 答案是:堆内存.(Tips:jdk1.8 已经将字符串常量池放在堆内存区) 题目考查的为Ja ...
- Java String:字符串常量池(转)
作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么? 字符串常量池的设计思想是什么? 字符串常量池在哪里? 如何操作字符串常量 ...
- String:字符串常量池
String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字 ...
随机推荐
- K8S系列第九篇(持久化存储,emptyDir、hostPath、PV/PVC)
更多k8s内容,请关注威信公众好:新猿技术生态圈 一.数据持久化 Pod是由容器组成的,而容器宕机或停止之后,数据就随之丢了,那么这也就意味着我们在做Kubernetes集群的时候就不得不考虑存储的问 ...
- 37岁Android程序员被裁员,面试大厂被拒,降薪去小公司,心更凉了
在职场论坛看到这样一个帖子,程序员小A被前公司裁员了,裁员之后也并没有特别气馁,打算重头再来,结果却被现实打击到了. 他大学毕业的时候进入到一家知名互联网公司上班,工作期间,也是不断学习,提升自己的能 ...
- 图 邻接表 邻接矩阵 BFS生成树 DFS生成树
- Python - typing 模块 —— 常用类型提示
前言 typing 是在 python 3.5 才有的模块 前置学习 Python 类型提示:https://www.cnblogs.com/poloyy/p/15145380.html 常用类型提示 ...
- WPS:利用数据透视表将数据按指定列进行分组求和
1.场景 如图所示:根据日期计算日期当天的总金额 2.利用数据透视表完成该操作 (1)选择金额列的某一格数据,点击上方插入--数据透视表 !!请确保表格第一行为表头 (2)在弹出的页面中直接点击&qu ...
- 使用F#编写PowerShell模块
▲F#和PowerShell模块 作为可能是人类世界最强大的Shell,PowerShell最大的特点是能够直接在命令间传递.NET对象,而支持这种能力的命令被称作cmdlet.自己编写PowerSh ...
- windows上解决git每次重复输入账号密码
win7电脑: 1.在 C:\Users\Administrator 下 编辑 .gitconfig文件 2.在原有内容下添加一行(此行作用为自动保存,保存修改后再使用一次GIT,输入账号密码后下次即 ...
- 05.SpringMVC之请求映射
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或者方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. @RequestMapping注解有六个属性,下面进 ...
- 对集合使用Comparator
1 import java.util.Comparator; 2 import java.util.PriorityQueue; 3 4 /** 5 * 对集合使用Comparator,不改变对象的自 ...
- Java学习之 多态 Polymorphism
转自:http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html 多态的概念 多态==晚绑定. 不要把函数重载理解为多态. 因为多态是一 ...