串池StringTable与s.intern()方法 、 验证s.intern()方法(基于jdk1.8)(附1.6对比)
验证s.intern()方法(基于jdk1.8)(附1.6对比)
1、在 jdk1.8中 s.intern()方法指的是尝试将字符串对象s放入串池中 :如果串池中有,则不会放入;若没有,放入(和堆中为同一对象)。
-
最终返回的是串池中的对象(不论放不放入)
-
如:String s1 = s.intern(); s1指的是串池中的常量对象
2、下面是两个测试横向对比(1.8环境):
两个方法不同之处:
-
主要在执行String s1 = s.intern() 前后,具体看下面测试方法的注释
-
导致两个方法中最后一行System.out.println("ab" == s) 输出不同
测试一:执行String s1 = s.intern() 前放入"ab"
//最终串池中对象StringTable["a", "b", "ab" ] public static void main(String[] args) { //vm调用StringBuild.append("a").append("b").toString() 最终相当于变成 new String("ab") String s = new String("a") + new String("b"); //*****线程此时串池中对象StringTable["a", "b"] //堆内存: new String("a") new String("b") new String("ab") System.out.println("ab" == s); //false 串池中没有"ab",此次会将 "ab"常量放入串池 因为 s在堆内存中,"ab"在串池中内存地址不同 //****此时串池中对象StringTable["a", "b", "ab"] //s.intern尝试将字符串对象s放入串池中 :如果串池中有,则不会放入;若没有,放入, 最终会返回串池中的对象 String s1 = s.intern(); //不会放入s,因为串池中已经存在 "ab" System.out.println("ab" == s1); //true 都是串池中的常量对象 ab System.out.println("ab" == s); //false s为堆内存地址 "ab"为串池中 }
测试二:执行String s1 = s.intern() 后放入"ab"
//最终串池中对象StringTable["a", "b", "ab" ] @Test public void test() { //vm调用StringBuild.append("a").append("b").toString() 最终相当于变成 new String("ab") String s = new String("a") + new String("b"); //简化等同于 String s = new String("ab"); //*****线程此时串池中对象StringTable["a", "b"] //堆内存: new String("a") new String("b") new String("ab") //s.intern尝试将字符串对象s放入串池中 :如果串池中有,则不会放入;若没有,放入, 最终会返回串池中的对象 String s1 = s.intern(); //放入s,因为串池中不存在 "ab" 之前代码行中未出现常量 "ab" System.out.println("ab" == s1); //true 都是串池中的常量对象 ab //****此时串池中对象StringTable["a", "b", "ab"] System.out.println("ab" == s); //true s、"ab"为串池中同一个常量 }
3、附:在 jdk1.6中 s.intern()方法指的是尝试将字符串对象s放入串池中 :如果串池中有,则不会放入;若没有,放入时为拷贝一份s对象放入
测试:
//最终串池中对象StringTable["a", "b", "ab" ] public static void main(String[] args) { String s = new String("a") + new String("b"); //*****线程此时串池中对象StringTable["a", "b"] String s1 = s.intern(); //拷贝一份s对象放入 //*****线程此时串池中对象StringTable["a", "b", "ab"] System.out.println("ab" == s1); //true 都是串池中的常量对象 ab System.out.println("ab" == s); //false s为堆内存地址 "ab"为串池中对象 }
# 总结:
-
1.6将常量对象放入常量池时拷贝,最终堆中和常量池中对象不同
-
1.8将常量对象放入常量池时直接将堆内存中对象放入,最终堆中和常量池中对象为同一个
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY