
Java 中创建 String 对象有两种常见方式:用字符串字面量(如 "hello")和用 new 关键字(如 new String("hello"))。它们的关键区别在于内存分配位置和对象复用机制,直接影响性能与 == 判断结果。
字符串常量池 vs 堆内存:位置决定是否共享
字符串字面量("abc")在编译期就确定,JVM 会将其放入字符串常量池(位于方法区,JDK 7+ 后移到堆中,但逻辑仍独立管理)。同一字面量多次出现,只会创建一个对象,后续引用都指向池中已有实例。
而 new String("abc") 每次都会在堆内存中新建一个 String 对象,即使内容相同,也和常量池中的对象不是同一个实例。
-
String a = "abc"; String b = "abc";→a == b为 true(指向常量池同一地址) -
String c = new String("abc"); String d = new String("abc");→c == d为 false(堆中两个不同对象) -
a == c也为 false(常量池 vs 堆,地址不同)
intern() 方法:手动触发常量池检查与复用
String.intern() 会检查常量池中是否存在相同内容的字符串:
立即学习“Java免费学习笔记(深入)”;
- 如果存在,直接返回池中引用;
- 如果不存在,将当前字符串对象(或其副本)加入池,并返回该引用。
例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
String s1 = new String("hello").intern();String s2 = "hello";System.out.println(s1 == s2); // true
注意:JDK 7+ 中,intern() 对已存在于堆中的字符串,会把它的引用存入常量池;JDK 6 中则会复制一份到永久代,行为略有不同。
实际开发建议:优先使用字面量,慎用 new
除非有明确需求(比如需要两个内容相同但独立的 String 对象用于某些反射或安全校验场景),否则应避免 new String("xxx")。
- 字面量更高效:避免无谓的对象创建和 GC 压力
- 语义更清晰:表达“这是一个固定值”,而非“我要新建一个字符串”
- == 判断需谨慎:比较内容一律用
.equals(),不要依赖 ==
一个小验证技巧:看内存地址变化
可以用 System.identityHashCode() 粗略观察对象是否相同(它返回对象的哈希码,对同一对象始终一致):
String x = "test";String y = "test";String z = new String("test");System.out.println(System.identityHashCode(x)); // 和 y 相同System.out.println(System.identityHashCode(z)); // 和 x/y 不同
这比直接打印对象更直观,且不依赖 toString() 重写。

















