【Java基础】String不可变性、String vs StringBuffer vs StringBuilder、常量池、intern()方法(附《思维导图》+《面试考点背诵版》)

发布时间:2026/5/19 20:56:09

【Java基础】String不可变性、String vs StringBuffer vs StringBuilder、常量池、intern()方法(附《思维导图》+《面试考点背诵版》) 文章目录Java 基础String不可变性、String vs StringBuffer vs StringBuilder、常量池、intern()方法一、String 不可变性核心本质1. 定义2. 底层源码原因3. 常见误区4. 不可变性四大优势二、String / StringBuffer / StringBuilder 三者终极对比核心执行逻辑开发使用规范三、字符串常量池String Pool1. 常量池位置2. 常量池作用3. 两种创建字符串方式重中之重方式1字面量创建 String s1 abc方式2new 创建 String s2 new String(abc)4. 相等判断规则5. 编译期优化四、intern() 方法 全网最全解析1. 方法作用2. JDK1.6 与 JDK1.7 核心区别面试必问JDK1.6永久代常量池JDK1.7堆内常量池3. 经典面试代码案例JDK1.84. intern() 使用场景五、高频面试考点汇总六、思维导图精简骨架面试背诵短句版一、面试极速背诵版精简口诀满分答案1. String不可变性2. String / StringBuilder / StringBuffer3. 字符串常量池4. intern() 方法二、10道高频面试真题含标准答案题1String为什么不可变题2String拼接底层原理是什么题3三者效率排序题4String s new String(xyz); 创建几个对象题5 和 equals 区别题6字符串常量池存在意义题7String s1ab 和 String s2xb 区别题8intern()方法JDK7之后变化题9为什么String适合做HashMap的key题10循环拼接字符串用哪个为什么三、必背代码结论JDK8环境Java String 全套【易混淆易错点对照表】一、不可变性 易错区分二、String / StringBuilder / StringBuffer 最强区分三、创建字符串 对象数量 超级易错四、拼接 编译期 运行期 分水岭1全常量拼接编译期优化2含变量拼接运行期五、 与 equals 生死区别六、字符串常量池 位置变迁面试必坑七、intern() 方法 JDK6 vs JDK7 最大坑点JDK1.6JDK1.7主流经典必考代码结论JDK8八、高频误区黑名单背完不踩坑九、最简答题万能模板Java 基础String不可变性、String vs StringBuffer vs StringBuilder、常量池、intern()方法一、String 不可变性核心本质1. 定义String 一旦创建内容无法修改任何修改字符串的操作都会生成新字符串原字符串不变。2. 底层源码原因String底层使用private final char[] value存储字符final修饰数组引用数组地址不可改private修饰外部无法直接修改数组元素无对外提供修改数组的方法彻底锁死内容3. 常见误区s xxx不是修改原字符串是新建对象replace()、substring()、trim()全都返回新 String不可变 ≠ 引用不可变String sa;sb只是引用指向改变4. 不可变性四大优势线程安全只读不可改多线程并发无冲突常量池复用节省内存相同字符串只存一份哈希值固定可安全作为 HashMap 键数据安全参数传递、网络传输不会被篡改二、String / StringBuffer / StringBuilder 三者终极对比特性StringStringBufferStringBuilder可变性不可变可变可变线程安全安全安全synchronized不安全效率极低频繁拼接大量创建新对象中等最高底层final char[]可变 char[] 扩容可变 char[] 扩容适用场景少量字符串定义、常量多线程拼接单线程大量拼接继承关系独立类继承 AbstractStringBuilder继承 AbstractStringBuilder核心执行逻辑String拼接新建对象海量拼接极度耗内存StringBuffer方法加锁并发安全加锁损耗性能StringBuilder无锁单线程最快并发会数据错乱开发使用规范日常字符串赋值、常量用String单线程循环拼接、日志、SQL拼接优先 StringBuilder多线程共享字符串拼接只能用StringBuffer三、字符串常量池String Pool1. 常量池位置JDK1.6 及之前方法区永久代JDK1.7移至堆内存重点考点2. 常量池作用缓存字面量字符串实现字符串复用减少重复对象创建节省堆内存。3. 两种创建字符串方式重中之重方式1字面量创建String s1 abc先去字符串常量池查找存在直接返回池中引用不存在在常量池创建对象返回引用只创建 1 个对象方式2new 创建String s2 new String(abc)先查常量池有无abc无常量池创建1个堆内存强制再新建1个 String 对象最少创建 2 个对象4. 相等判断规则Strings1abc;Strings2abc;Strings3newString(abc);s1 s2true同一常量池引用s1 s3false池内对象 ! 堆new对象s1.equals(s3)true比较内容5. 编译期优化常量拼接直接在编译期合并放入常量池Stringaab;// 编译直接变成 ab 进常量池变量拼接编译期无法优化走堆对象Stringxa;Stringbxb;// 堆中新对象不入常量池四、intern() 方法 全网最全解析1. 方法作用public native String intern()主动将字符串放入字符串常量池并返回池内引用2. JDK1.6 与 JDK1.7 核心区别面试必问JDK1.6永久代常量池常量池有该字符串返回池引用常量池没有复制一份放入永久代常量池返回新池引用堆对象和池对象完全独立JDK1.7堆内常量池常量池有直接返回池引用常量池没有不新建对象直接把堆中对象引用存入常量池实现堆对象 池对象内存极致优化3. 经典面试代码案例JDK1.8StringsnewString(1)newString(1);s.intern();Strings211;System.out.println(ss2);// true解析s是堆中11对象常量池无s.intern()把堆s的引用存入常量池s211直接复用池内堆引用两者指向同一堆对象 → true4. intern() 使用场景海量重复字符串手动入池节省内存统一字符串引用判断生效大数据、日志批量处理优化内存五、高频面试考点汇总String 为什么不可变final 数组私有无修改方法为什么推荐字符串拼接用 StringBuilder效率最高无锁new String() 创建几个对象1~2个常量池位置变化1.7从永久代移到堆变量拼接和常量拼接区别编译期优化intern() 1.6和1.7最大差异是否复用堆引用String 不可变好处安全、池化、哈希稳定六、思维导图精简骨架String体系 ├─ 不可变性 │ ├─ 底层final char[] │ ├─ 修改生成新对象 │ └─ 四大应用优势 ├─ 三类字符串对比 │ ├─ String不可变、低效 │ ├─ StringBuffer线程安全、中等 │ └─ StringBuilder单线程最快 ├─ 字符串常量池 │ ├─ 内存位置变迁 │ ├─ 字面量 / new 两种创建 │ └─ 编译期拼接优化 └─ intern()方法 ├─ 作用入池 ├─ JDK6 / JDK7 差异 └─ 实战内存优化面试背诵短句版一、面试极速背诵版精简口诀满分答案1. String不可变性底层private final char[] value存储字符不可变原因final锁数组地址、private禁止外部修改、无修改API修改本质所有增删改查方法都新建字符串原对象不变四大好处线程安全、常量池复用、hash值稳定、数据安全误区引用可变内容不可变2. String / StringBuilder / StringBufferString不可变拼接低效适合少量固定字符串StringBuffer可变加synchronized锁线程安全效率偏低StringBuilder可变无锁单线程效率最高线程不安全选型口诀常量用String、单拼用Builder、并发拼接用Buffer3. 字符串常量池位置JDK1.6永久代JDK1.7移至堆内存字面量创建String sabc→ 优先走常量池最多1个对象new创建new String(abc)→ 常量池堆最少2个对象编译优化常量直接拼接编译期合并入池变量拼接生成堆新对象4. intern() 方法作用将字符串主动放入常量池返回池中引用JDK1.6无则复制新对象进永久代堆与池不是同一对象JDK1.7无则直接存堆对象引用堆和池指向同一个用途海量字符串去重、节省内存、统一引用判断二、10道高频面试真题含标准答案题1String为什么不可变答底层由**private final char[]**存储final保证数组引用不可修改private禁止外部访问修改类中没有提供修改字符数组的方法所以内容一旦创建无法更改。题2String拼接底层原理是什么答JDK8底层会自动创建StringBuilder进行append拼接最后toString转String循环内频繁会频繁创建销毁Builder性能极差。题3三者效率排序答StringBuilder StringBuffer String题4String s new String(“xyz”); 创建几个对象答常量池无xyz2个常量池1个堆1个常量池已有1个仅堆对象。题5 和 equals 区别答比较内存地址equals默认比较地址String重写后比较内容。题6字符串常量池存在意义答复用字符串对象减少内存占用避免大量重复字符串创建提升性能。题7String s1ab和String s2xb区别答s1编译期优化为ab直接入常量池s2是变量拼接运行时创建堆中新对象不入常量池。题8intern()方法JDK7之后变化答池中没有该字符串时不再创建新对象直接把堆内对象引用存入常量池实现堆对象与池对象同一地址。题9为什么String适合做HashMap的key答不可变hashCode值固定不会变动导致找不到键线程安全。题10循环拼接字符串用哪个为什么答用StringBuilder可变字符数组只扩容不新建对象无线程锁执行效率最高。三、必背代码结论JDK8环境// 1Strings1abc;Strings2abc;s1s2 →true// 2Strings3newString(abc);s1s3 →false// 3StringsnewString(1)newString(1);s.intern();Strings411;ss4 →trueJava String 全套【易混淆易错点对照表】一、不可变性 易错区分错误认知正确结论String 引用不能变引用可以变内容不能变s拼接修改原字符串每次拼接新建新对象原对象不变substring 截取修改原串全部返回新字符串final String 就不可改final只限制引用内容依旧遵循不可变一句话记地址可改字符内容永不可改。二、String / StringBuilder / StringBuffer 最强区分对比点StringStringBufferStringBuilder可变❌ 不可变✅ 可变✅ 可变线程安全安全✅ 安全(sync加锁)❌ 不安全效率最低中等最高底层final char[]动态char[]动态char[]循环拼接极慢较慢最快推荐场景常量、固定文本多线程拼接单线程所有拼接死记口诀常量用String并发用Buffer日常全用Builder三、创建字符串 对象数量 超级易错String s abc池中有0个新对象池中无1个常量池对象String s new String(abc)池中有只在堆创建1个池中无常量池1个 堆1个 2个必考结论new 最少1个最多2个。四、拼接 编译期 运行期 分水岭1全常量拼接编译期优化Stringsabc;编译直接变成abc直接入常量池2含变量拼接运行期Stringaa;Stringsab;底层new StringBuilder拼接生成堆对象不入常量池判断口诀全字面量编译优化有变量堆新对象五、 与 equals 生死区别比内存地址equalsString重写比字符串内容abcnewString(abc)→falseabc.equals(newString(abc))→true业务开发一律用equals判相等六、字符串常量池 位置变迁面试必坑JDK1.6 及以前方法区永久代JDK1.7 ~ JDK17移到堆 Heap目的永久代内存不足方便GC回收闲置字符串七、intern() 方法 JDK6 vs JDK7 最大坑点JDK1.6池内没有 →新建一份字符串放进永久代堆对象 ≠ 池对象地址不同JDK1.7主流池内没有 →直接把堆对象引用存入常量池堆对象 池对象地址完全一致经典必考代码结论JDK8StringsnewString(1)newString(1);s.intern();Strings211;System.out.println(ss2);// true调换顺序直接变falseStrings211;StringsnewString(1)newString(1);s.intern();System.out.println(ss2);// false八、高频误区黑名单背完不踩坑误区String不可变就不会产生垃圾正解频繁拼接产生大量废弃字符串极易造成内存浪费误区循环里直接用拼接没事正解循环内会疯狂创建销毁Builder性能雪崩误区intern()一定会节省内存正解少量字符串没必要海量重复字符串才适合用误区StringBuffer比StringBuilder快正解相反Builder无锁更快误区常量池所有字符串都会被永久保存正解JDK7后在堆闲置可被GC回收九、最简答题万能模板问不可变private final char[] 无修改方法问拼接选谁单线程StringBuilder多线程StringBuffer问new几个对象字面量1个new最多2个问intern区别6复制对象7存堆引用问拼接原理常量编译合并变量底层Builder

相关新闻