在 Java 中,什么条件下两个 String 会是同一个对象?
admin
2024-03-27 17:23:09
0

这段时间工作上经常用遇到 String 对象比较的问题,这是一个比较基础的问题,但有时候对其原因还是有些迷惑,所以稍微总结一下。

一、核心要点

今天我们来讲讲 Java 语言中的 String,在一定条件下两个 String 会是同一个对象,这是怎么回事呢?Java 语言中的 String 相信大家都很熟悉,但是 Java 语言中的两个 String 什么条件下会是同一个对象是怎么回事呢,下面就让小编带大家一起了解吧。

Java 语言中的两个 String 什么条件下会是同一个对象,其实就是两个 String 相等的情况下会是同一个对象,大家可能会很惊讶 Java 语言中的两个 String 怎么会是同一个对象呢?但事实就是这样,小编也感到非常惊讶。

这就是关于 Java 语言中的 String 在什么条件下两个 String 会是同一个对象的事情了,大家有什么想法呢,欢迎在评论区告诉小编一起讨论哦!

二、基础知识

2.1 String 是什么?

String 不同于其他 8 大基础数据类型,它是一个对象。它还是一个比较特殊的对象,因为他还可以通过 = 直接赋值。

2.2 常量池介绍

在 JAVA 中常量池分三种。

对于 Integer 和 Long 等基础数据类型的包装类也有类似的常量缓存,本文就不详细说明了。

Class 常量池:

Class 常量池存放在 *.class 文件中,在编译阶段生成,也被称为静态常量池,用于存储字面量和符号引用。字面量主要包含文本字符串、被声明为 final 的常量值和基本数据类型的值,符号引用则包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。

运行时常量池:

运行时常量池包也被称为动态常量池,但 class 文件被加载到内存后,虚拟机会将 class 文件常量池里的内容转移到运行时常量池。运行时常量池具有动态性,运行期间也可能将新的常量放入池中。

字符串常量池:

字符串常量池又称为字符串池,全局字符串池,本质上是个 HashSet,是一个纯运行时的常量池。字符串常量池是 JVM 为了提升性能,避免字符串重复创建而维护的一块特殊的内存空间,用于存储堆中字符串对象的引用。

2.3 两种不同的创建方式

字面量赋值:

String s = "nineya";

这种创建方式 JVM 将搜索字符串常量池中是否存在需要创建的 nineya 字符串的地址引用,如果不存在则会在堆中开辟空间存储字符串对象,常量池中开辟空间存储该字符串对象的地址引用,如果存在则直接使用常量池中引用的地址。在栈中也将开辟空间,用于存储字符串的地址值。

用new创建:

String s = new String("nineya");

这种创建方式 JVM 也将搜索字符串常量池中是否存在需要创建的 nineya 字符串的地址引用,如果不存在则会在堆中开辟空间存储字符串对象,常量池中开辟空间存储该字符串对象的地址引用,如果存在则直接使用常量池中引用的地址。

除此之外,在堆和栈中也将会开辟空间,堆空间中将创建一个字符串对象,引用常量池中引用的字符串对象的字符内容,栈空间则存储堆中字符串对象的地址。

三、字符串比较

比较一:

String s1 = "nineya";
String s2 = "nineya";
System.out.println(s1 == s2);// 输出结果为:true

如上代码 JVM 将会把 2 个 nineya 字符串都作为字面量放入 Class 常量池,然后在类加载阶段创建字符串实例,并在字符串常量池中存储其引用,所以它们会是同一个对象。

比较二:

String s1 = new String("nineya");
String s2 = new String("nineya");
System.out.println(s1 == s2);// 输出结果为:false

如上 s1s2 都使用 new 进行创建,将在堆中新创建一个字符串对象,所以不会是同一个对象。

比较三:

final String s1 = "nineya";
String s2 = s1 + ".com";
String s3 = "nineya.com";
System.out.println(s2 == s3);// 输出结果为:true

由于 s1final 关键字修饰,所以 s1.com 的拼接在编译时便会直接完成,都将被放入 Class 常量池,所以 s2s3 是同一个对象。

比较四:

String s1 = "nineya";
String s2 = s1 + ".com";
String s3 = "nineya.com";
System.out.println(s2 == s3);// 输出结果为:false

由于 s1 是一个变量,所以 s1.com 的拼接将使用 StringBuilderappend 方法生成新对象,不会搜索字符串常量池,而 s3 依旧是常量池引用的对象,所以 s2s3 不是同一个对象。

比较五:

String s1 = "nineya";
String s2 = s1 + ".com";
String s3 = "nineya.com";
System.out.println(s2.intern() == s2);
System.out.println(s2.intern() == s3);
System.out.println(s3 == s3.intern());// 输出结果为:false/true/true

intern() 方法的作用是判断字符串常量池是否存在当前字符串的常量,如果存在则取出该常量,如果不存在则将当前对象放入常量。

由于 s3 在类加载时已经被放入字符串常量池了, 所以 s2.intern() 取出的字符串对象是 s3,所以 s2.intern() == s2 不是同一个对象为 falses2.intern() == s3 是同一个对象为 true

s3 就是字符串常量对象,所以 s3.intern() 取出的对象为其本身,所以 s3 == s3.intern()true

相关内容

热门资讯

原创 三... 小暑一过,这天儿就跟糊了层保鲜膜似的,闷得人喘不上气儿。走两步路,后背就黏糊糊的,晚上躺床上翻来覆去...
原创 煮... 咱今儿个来唠唠福寿螺这玩意儿哈。你瞧,福寿螺这东西,打从被引进咱国内后,那可真是 “名声大噪”,不过...
海外华裔大学生海南研习行:一碗... 中新网海口7月12日电 (记者 张茜翼)“嗦——”一声轻响,18岁的澳大利亚海南籍华裔大学生黎锦辉将...
如何恢复自己昔日的辉煌? 如何恢复自己昔日的辉煌?既然都知道自毕隐渗己的不足了,那就得努力改正,现在还是小学,很多携陵坏习惯只...
形容夏天的成语。[肉山脯林]是... 形容夏天的成语。[肉山脯林]是什么意思 ?赤日炎炎 绿树成荫 挥汗如雨 绿树成荫 挥汗如雨 蝉声阵...
准爸爸在胎教中的职责有哪些 准爸爸在胎教中的职责有哪些胎教是一个家庭的事,不能单把胎教的责任推给宝妈,作为宝爸也是有责任的,虽然...
鹿_的读音鹿_的读音是什么 鹿_的读音鹿_的读音是什么鹿_的读音是:lùmí。鹿_的拼音是:lùmí。注音是:ㄌㄨ_ㄇ一_。结构...
雅雅的解释 雅雅的解释雅雅的解释词语分解 雅的解释 雅 ǎ 正规的, 标准 的:雅言。 雅正 (a.规范的;b...
初三的六一儿童节中小马哥死了吗 初三的六一儿童节中小马哥死了吗初三汪纤判的六一儿童节中,小马哥没有死。港风巨制小说《初三的六一儿童节...
吴三桂为了陈圆圆而反叛,还有哪... 吴三桂为了陈圆圆而反叛,还有哪些一怒为红颜的历史典故?吕布为了貂蝉和董卓闹翻,春秋时期的夏姬,号称“...
赵兰梅和孙明明的关系 赵兰梅和孙明明的关系赵兰梅和孙明明的关凯尘系是:1、岳母与女婿关系。赵兰梅是孙明明的岳母,孙明明是赵...
课前三分钟演讲(哲理故事+分析... 课前三分钟演讲(哲理故事+分析)初二的水平..其实就是1、2个哲理故事,最后加上总结性的分析 1—2...
天珠变里周维清说的那个色老头是... 天珠变里周维清说的那个色老头是谁?周维清的天珠一共有六种属性,分别是风、雷、黑暗、空间、邪恶、时间目...
神秘的什么作文,要写成童话故事 神秘的什么作文,要写成童话故事神秘的花园、、、童话故事= =这题材真没写过。不过可以写成小小说的模式...
小学二年级编写一个和数学有关的... 小学二年级编写一个和数学有关的小故事,急?我有一个好朋友,它的名字叫“数学”,现在让我来告诉你关于“...
你觉得哪个男星是小鲜肉无论怎么... 你觉得哪个男星是小鲜肉无论怎么努力都无法超越的?那只能是有韵味的大叔是小鲜肉无法逾越的。最近看《吐槽...
都市异能小说,主角要无敌。 都市异能小说,主角要无敌。比如中国龙组,超级学生..都市类..出来就无敌了..无郁闷疯狂内功..都市...
昨天去幼儿园接女儿的时候,听到... 昨天去幼儿园接女儿的时候,听到别的家长提到一个童装品牌Bonpoint,这是个什么牌子?Bonpoi...
新疆十五天高端深度游每人多少?... 七月的新疆,简直是上帝打翻的调色盘!琼库什台大环线的风光更是美得让人挪不开眼,草原像铺了层厚厚的绿绒...
文旅焕彩春城夜 避暑休闲乐逍遥 当夏日的热浪奔涌而来,绿草如茵的露营地成为人们心目中的消夏好去处。7月11日傍晚,青怡坊云琅城市露营...