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 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字 ...
随机推荐
- Spring Cloud Alibaba - Spring Cloud Stream 整合 RocketMQ
Spring Cloud Stream 简介 在微服务的开发过程中,可能会经常用到消息中间件,通过消息中间件在服务与服务之间传递消息,不管你使用的是哪款消息中间件,比如RabbitMQ.Kafka和R ...
- 面试官:实现一个带值变更通知能力的Dictionary
如题, 你知道字典KEY对应的Value什么时候被覆盖了吗?今天我们聊这个刚性需求. 前文提要: 数据获取组件维护了业务方所有(在用)的连接对象,DBA能在后台无侵入的切换备份库. 上文中:DBA在为 ...
- Qt Designer中自定义控件的使用(提升法与插件法)
准备乱写一点Qt自定义Widget在Designer中的使用.可是又不想重复提升法(promotion)及插件法基本用法,因为Manual中Using Custom Widgets with Qt D ...
- SSM集成FastJson
FastJson Json数据格式回顾 什么是json JSON:(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于 ECMAScript( ...
- 【XSS-labs】Level 11-15
Level 11 和level 10 差不多的页面,传参后查看页面源代码:依旧是第3个可以正常传参. 尝试level 10 的payload 发现 " 被实体化 可以打开控制台将第三个inp ...
- STM32—4线SPI驱动SSD1306 OLED
文章目录 一.OLED简介 二.驱动SSD1306所需知识 1.引脚介绍 2.通信时序 3.显存GRAM 4.字库 5.SSD1306基本命令 三.代码讲解 1.相关引脚配置 2.模拟SPI通信 3. ...
- 带头撸抽奖系统,DDD + RPC 开发分布式架构!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.咋,撸个项目? 总有粉丝伙伴问傅哥,有没有能上手练习技术的项目,现在学了这么多技术知识.看 ...
- 熟悉而陌生的新朋友——IAsyncDisposable
本文作者--句幽 在.NET Core 3.0的版本更新中,官方我们带来了一个新的接口 IAsyncDisposable. 小伙伴一看肯定就知道,它和.NET中原有的IDisposable接口肯定有着 ...
- mongodb+docker数据卷实现数据持久化
# 拉取镜像docker pull mongo:4.0.22# 启动容器,挂载本地目录 docker run -itd --name mongo -p 27017:27017 -v $PWD/mong ...
- MySQL 数据库、数据表、数据的基本操作
1.数据库(database)管理 1.1 create 创建数据库 create database firstDB; 1.2 show 查看所有数据库 mysql> show database ...