乐于分享
好东西不私藏

全网最通透的 String 源码解读!看完这篇,面试再也不怕被问 String

本文最后更新于2026-03-11,某些文章具有时效性,若有错误或已失效,请在下方留言或联系老夜

全网最通透的 String 源码解读!看完这篇,面试再也不怕被问 String

大家好,我是云扬。
日常写 Java 业务代码,String 基本是敲得最多的类。但很多同学只停留在equalssubstringindexOf调用层面,一到面试:
  • 为什么 String 不可变?

  • JDK9 为什么改成 byte []?

  • hashCode 为什么用 31?

  • substring 有什么坑?

直接懵圈。
今天这篇,带你吃透 String 源码 + 实战 + 面试点,公众号排版,适合收藏、转发、复习。

一、先看 String 本质:为什么设计成不可变?

打开 String 源码,第一眼长这样:
public final class String    implements java.io.Serializable, Comparable<String>, CharSequence {    // JDK8    // private final char value[];    // JDK9+    private final byte[] value;    private final byte coder;}
三个关键点:
  1. 类被 final:不能被继承,没有子类

  2. 底层数组被 final:引用不能改,内容也不提供修改入口

  3. 所有方法都不修改原对象:截取、替换、切割全是返回新 String

好处:
  • 线程安全,不用加锁

  • 适合做 HashMap  key

  • 字符串常量池可以安全复用


二、JDK8 → JDK9:String 内存大优化

这是面试 / 调优必问:为什么换成 byte []?

JDK8 及以前

privatefinalcharvalue[];
  • char 固定2 字节

  • 英文、数字也占 2 字节 → 内存浪费

JDK9 及以后(现在主流)

privatefinalbyte[]value;privatefinalbytecoder;
  • byte[]存储

  • coder 标记编码:

      • 0:Latin-1(英文数字,1 字节)
      • 1:UTF-16(中文等,2 字节)
    一句话总结:纯英文省一半内存,中文正常存,GC 更轻松。

    三、hashCode ():31 这个魔数到底为啥?

    private int hash;publicinthashCode() {    int h = hash;    if (h == 0 && value.length > 0) {        byte[] val = value;        for (int i = 0; i < value.length; i++) {            h = 31 * h + (val[i] & 0xff);        }        hash = h;    }    return h;}
    亮点:
    1. hash 缓存:算一次就存起来,不再重复算

    2. 乘 31这就是 String 天生适合做HashMap 键的原因。


    四、高频方法:源码 + 实战一把抓

    1. substring 截取(左闭右开)

    public String substring(int beginIndex, int endIndex) {    checkBoundsBeginEnd(beginIndex, endIndex, length());    if (beginIndex == 0 && endIndex == length())        return this;    return isLatin1()         ? StringLatin1.newString(...)         : StringUTF16.newString(...);}
    实战:
    String str = "Hello,Java-String-云扬";String sub1 = str.substring(610);String sub2 = str.substring(6);System.out.println(sub1);  // JavaSystem.out.println(sub2);  // Java-String-云扬

    注意:截取都会返回新字符串


    2. indexOf 查找

    String str = "java-string-cloud-java";int idx1 = str.indexOf('j');            // 0int idx2 = str.indexOf("string");       // 5int idx3 = str.indexOf('j'5);         // 18
    底层就是遍历数组匹配,时间复杂度 O (n)。

    3. 必用工具方法

    String str = "JavaBlog";str.length();        // 长度str.isEmpty();       // 是否空str.charAt(2);       // 取第3个字符str.trim();          // 去首尾空格String.valueOf(1024); // 任意类型转字符串

    五、一张图总结 String 核心

    • final 类 + final 数组 = 不可变

    • JDK9+ byte[] + coder = 省内存

    • hashCode 缓存 + 31 哈希 = 适合做 Map Key

    • 所有修改都返回新对象 = 安全、线程安全

    日常开发建议:
    • 少量拼接:直接 +

    • 大量拼接 / 循环拼接:StringBuilder


    我是云扬,专注Java 后端 & 源码实战。干货持续更新,建议星标 / 收藏,面试前直接翻出来看。

    本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » 全网最通透的 String 源码解读!看完这篇,面试再也不怕被问 String

    猜你喜欢

    • 暂无文章

    评论 抢沙发

    9 + 2 =