Java 中 String 的字面量与 intern 方法
下方代码主要说明:
String b = new String("xyz") 创建2个对象,一个在常量池中的 "xyz",一个 String 实例对象,返回的是实例对象引用。
intern() 方法有两个作用,一是取出 String Pool 中的值(可能是字面量可能是引用),二是如果 String Pool 没有该值,则将String 对象引用添加到 String Pool
String a = "abc" 该表达式有两个作用,一是取出 String Pool 中的值并返回(可能是字面量可能是对象的引用),二是如果 String Pool 没有该值,则将 字面量添加到 String Pool
检测代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class Test { @org .junit.Test public void test() { String s1 = new String( "x" ) + new String( "yz" ); //这里的 new String 会创建5个对象,3个实例,2个字面量,存入 "x", "yz" 2 个字面量。 //返回 "xyz" 的引用 String l_s1 = s1.intern(); //当常量池中没有该字面量或引用时,则把该字符串对象的引用添加到常量池中,并返回引用 String s2 = "xyz" ; printHash(l_s1); //引用 printHash(s1); //引用 printHash(s2); //当常量中有该字符串的引用,返回引用 String s3 = new String( "abc" ); //生成 2个对象,1个实例,1个 "abc" 字面量。存入 "abc" 字面量,返回 "abc" 引用 String s4 = "abc" ; String l_s3 = s3.intern(); //与前面对比,可知常量池中确实有该字符串,返回的是字面量 printHash(l_s3); //字面量 printHash(s3); //引用 printHash(s4); //字面量 String s = "s" ; //存入该字面量,返回该字面量 printHash(s.intern()); //字面量 printHash(s); //字面量 } private void printHash(String str) { int hash = System.identityHashCode(str); System.out.println(str.hashCode() + " : " + hash); } } |
返回结果:
1 2 3 4 5 6 7 8 | 119193 : 476800120 119193 : 476800120 119193 : 476800120 96354 : 1744347043 96354 : 1254526270 96354 : 1744347043 115 : 662441761 115 : 662441761 |
下方代码说明:
new String("xyz") 会生成 2 个对象,而 new String(bytes) 只生成一个对象
检测代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class Test { @org .junit.Test public void test() { char [] bytes = new char []{ 'a' , 'b' , 'c' }; String s1 = new String(bytes); String l_s1 = s1.intern(); String s2 = "abc" ; printHash(s1); printHash(l_s1); printHash(s2); String s3 = new String( "xyz" ); String l_s3 = s3.intern(); String s4 = "abc" ; printHash(s3); printHash(l_s3); printHash(s4); } private void printHash(String str) { int hash = System.identityHashCode(str); System.out.println(str.hashCode() + " : " + hash); } } |
返回结果
1 2 3 4 5 6 | 96354 : 476800120 96354 : 476800120 96354 : 476800120 119193 : 1744347043 119193 : 1254526270 96354 : 476800120 |
总结:
在不同情况下 new String(param) 方法或 "abc" 会生成字面量与引用。那么考虑一般情况,在使用 new String("abc") 或 String s = "abc" ,通常会生成字面量。使用 new String(bytes) 通常不会自动生成字面量,需要调用 new String(bytes).intern() 方法。
补充:
1. 对象的 hashCode 方法与 System.identityHashCode 区别 :一般情况下 hashCode 等同于 identityHashCode。但是由于下一条中的因素,会导致不相等。
2. 当对象的 equals 方法重写时,也需要正确重写对象的 hashCode 方法。一个原则是,equals 相等,hashCode 必须相等。而 hashCode 相同,equals 可以不相等。在该对象作为字典中的 key 涉及到 Hash 存取时,判断是否相等先使用 hashCode 判断,再使用 equals 判断,这样可以提高效率。(分析见 参考)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix