You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中String类型的==运算符行为疑惑及代码问题解析

理解Java中==运算符对String的行为

测试代码

String name = "Object Oriented";
String str1 = "Object";
String str2 = "Object";
String str3 = new String("Object");
String str4 = name.substring(0,6);
String str5 = name.substring(0,6);
String str6 = "Obj" + "ect";

System.out.println(str1 + "==" + str2 + ": " + (str1 == str2));
System.out.println(str1 + "==" + "Object" + ": " + (str1 == "Object"));
System.out.println(str1 + "==" + str6 + ": " + (str1 == str6));
System.out.println(str1 + "==" + str3 + ": " + (str1 == str3));
System.out.println(str1 + "==" + str4 + ": " + (str1 == str4));
System.out.println(str4 + "==" + str5 + ": " + (str4 == str5));

运行输出

Object==Object: true
Object==Object: true
Object==Object: true
Object==Object: false
Object==Object: false
Object==Object: false

参考资料

为节省内存,Java会将所有内容相同的字符串字面量视为单个String对象,拥有多个指向它的引用。
——Deitel《Java How to Program》

疑问与解答

我理解str1、str2、str6因属于字符串字面量或编译期确定的字面量拼接,指向同一对象,结果为true;str3通过new创建新对象,结果为false。但我不理解最后两个结果:str4与str6、str2与str5的区别是什么?str1是变量而其他是对象吗?我已了解equals()方法及二者的区别,此问题与Stack Overflow相关问题不同,寻求解答。

核心原因解析

  • 字符串常量池的作用范围:只有编译期就能确定值的字符串字面量/常量表达式才会被放入字符串常量池。str6的"Obj"+"ect"是编译期常量拼接,编译器会直接优化成"Object",所以它会指向常量池中的同一个对象。
  • substring方法的行为:substring是运行期执行的方法,它返回的是新创建的String对象(JDK 7及以后版本中,substring会直接生成新的字符数组,不再共享原数组,但核心是会创建新对象),不会放入字符串常量池。所以str4和str5都是运行期生成的新对象,它们和常量池中的str1指向不同的内存地址,彼此之间也不是同一个对象,因此==比较结果为false。
  • 变量与对象的区别:str1是引用变量,它指向常量池中的String对象;str4、str5是引用变量,指向的是运行期创建的堆内存中的String对象。本质上所有的String类型变量都是引用,区别在于它们指向的对象是在常量池还是堆中,以及是否是同一个对象实例。

内容的提问来源于stack exchange,提问作者babeyh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 19:52:38