第31.1篇Java常用API与底层原理对比集2026版系列导航《Java 100 天进阶之路》完整目录 |⬅️ 上一篇第31篇Java数组详解 |➡️ 下一篇第32篇Java常用工具类️ 本文阅读地图2 分钟速览常用 API 是开发中的“日常工具”也是面试中容易忽视的考点。本文汇总 10 组高频易混淆概念每组配一句话总结 详细对比编号对比组一句话区分1String vs StringBuilder vs StringBufferString 不可变Builder 快线程不安全Buffer 慢线程安全2字符串常量池 vs 堆字面量在池中复用new String()在堆中新建3wait()vssleep()wait 释放锁需 notifysleep 不释放锁时间到自醒4notify()vsnotifyAll()唤醒一个 vs 唤醒全部5EnumMapvsHashMapEnumMap 专为枚举设计效率更高6DatevsLocalDateDate 旧可变/线程不安全LocalDate 新不可变/线程安全7SimpleDateFormat线程安全问题内部有 Calendar 共享状态多线程需注意8直接缓冲区 vs 堆缓冲区直接缓冲区减少拷贝适合网络堆缓冲区受 GC 管理9flip()vsrewind()vsclear()flip 写→读rewind 重读clear 重置10枚举 vs 普通常量类枚举类型安全支持方法、单例文章目录第31.1篇Java常用API与底层原理对比集2026版️ 本文阅读地图2 分钟速览一、核心知识点概览二、逐组对比详解对比1String vs StringBuilder vs StringBuffer对比2字符串常量池 vs 堆对比3wait() vs sleep()对比4notify() vs notifyAll()对比5EnumMap vs HashMap对比6Date vs LocalDate对比7SimpleDateFormat 线程安全问题对比8直接缓冲区 vs 堆缓冲区对比9flip() vs rewind() vs clear()对比10枚举 vs 普通常量类三、避坑要点四、练习题 你的学习进度 下一篇文章预告一、核心知识点概览本篇文章涵盖 Java 常用 API 与底层原理中 10 组最高频的易混淆概念来源于第21~31篇的全部内容篇号涉及对比数量第21篇Object 方法扩展—第22篇String vs StringBuilder vs StringBuffer、常量池2组第23篇直接缓冲区 vs 堆缓冲区、flip/rewind/clear2组第24篇枚举 vs 常量类、EnumMap vs HashMap2组第26篇注解扩展—第27篇代理扩展—第28篇反射扩展—第29-30篇Date vs LocalDate、SimpleDateFormat 线程安全2组第31篇数组扩展—二、逐组对比详解对比1String vs StringBuilder vs StringBuffer对比维度StringStringBuilderStringBuffer可变性❌ 不可变✅ 可变✅ 可变线程安全✅ 安全不可变❌不安全✅安全synchronized性能拼接时低最高较低同步开销适用场景少量拼接/不可变单线程、频繁拼接多线程、频繁拼接引入版本Java 1.0Java 5Java 1.0 一句话总结String 不可变安全但拼接慢StringBuilder 单线程神器StringBuffer 多线程安全但慢。对比2字符串常量池 vs 堆对比维度字符串常量池堆存储位置方法区元空间堆存储内容字面量字符串复用new String()创建的对象是否复用✅ 相同字符串共用一份❌ 每次new创建新对象垃圾回收可回收但频率低正常 GC 回收代码验证Strings1hello;// 常量池Strings2hello;// 复用池中对象Strings3newString(hello);// 堆中新建System.out.println(s1s2);// trueSystem.out.println(s1s3);// false对比3wait()vssleep()对比维度wait()sleep()所属类Object 实例方法Thread 静态方法是否释放锁✅释放锁❌不释放锁唤醒方式notify()/notifyAll()时间到自动醒来使用位置必须在synchronized中任何地方线程状态WAITINGTIMED_WAITING对比4notify()vsnotifyAll()对比维度notify()notifyAll()唤醒数量唤醒一个等待线程唤醒所有等待线程选择哪个线程JVM 随机选择全部唤醒适用场景一个生产者一个消费者多个生产者/消费者对比5EnumMapvsHashMap对比维度EnumMapHashMap键类型只能是枚举类型任意类型底层实现数组枚举常量索引数组链表红黑树性能更高直接数组访问较低哈希计算null 键❌ 不允许✅ 允许适用场景键是枚举类型时优先使用通用 Map对比6DatevsLocalDate对比维度java.util.Datejava.time.LocalDate可变性❌ 可变✅不可变线程安全❌ 不安全✅安全月份起始从 0 开始1月0从 1 开始1月1年份从 1900 开始正常年份是否推荐❌ 推荐使用✅推荐Java 8对比7SimpleDateFormat线程安全问题问题根源SimpleDateFormat内部维护一个Calendar对象引用多线程共享时一个线程修改 Calendar 状态会影响其他线程导致解析错误或异常。解决方案✅方案一每次使用时创建新实例最简单✅方案二使用ThreadLocal包装✅方案三使用DateTimeFormatterJava 8线程安全对比8直接缓冲区 vs 堆缓冲区对比维度直接缓冲区堆缓冲区内存位置系统本机内存NativeJVM 堆内存GC 管理❌ 不受 GC 管理✅ 受 GC 管理数据拷贝次数1 次少一次拷贝2 次堆→Native 再传输分配速度慢系统调用快适用场景大文件、网络 I/O小数据、通用场景对比9flip()vsrewind()vsclear()方法作用positionlimitflip()写→读模式切换0原 positionrewind()重新读不改变 limit0不变clear()重置准备写0capacity对比10枚举 vs 普通常量类对比维度枚举enum普通常量类类型安全✅ 编译期检查❌ 可能传入非法值方法✅ 可以有方法❌ 只有常量单例✅ 天然单例❌ 需手动实现反射攻击✅ 防止❌ 可反射修改三、避坑要点错误/误区后果正确做法循环中用拼接字符串性能极差用StringBuilder用比较字符串内容可能 false用equals()多线程共享SimpleDateFormat解析错误/异常用ThreadLocal或DateTimeFormatter使用Date的废弃构造方法代码不可靠用LocalDate忘记flip()直接读 Buffer读不到数据写后读前flip()四、练习题代码题String s1 abc; String s2 new String(abc);s1 s2的结果是什么为什么改错题下面的代码有什么问题如何修复SimpleDateFormatsdfnewSimpleDateFormat(yyyy-MM-dd);// 多个线程共享 sdf选择题ByteBuffer 写数据后要切换到读模式应该调用哪个方法A.clear()B.rewind()C.flip()D.reset() 你的学习进度当前第31.1篇 ·基础篇外挂常用API与底层原理对比集✅ 已完成基础篇第1~31篇 第4.1篇 第20.1~20.2篇 第31.1篇 正在学第31.1篇⏳ 待学习第32~44篇主体 更多外挂篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 下一篇文章预告下一篇《第32篇Java常用工具类》内容简介Objects、Collections、Arrays 工具类使用与对比。《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送