讲解

String 是 Java 中使用频率最高的类型,但它不是基本类型,而是类(引用类型)。String 最重要的特性是不可变(immutable):一个字符串对象创建之后内容永远不会变,所有看似「修改」字符串的方法(toUpperCase、replace、substring)实际上都是返回一个全新的字符串对象,原字符串纹丝不动。这个设计让字符串可以安全地共享和缓存,但也意味着频繁拼接会产生大量临时对象。

常用方法要练熟:length() 求长度、charAt(i) 取下标为 i 的字符(下标从 0 开始)、substring(起, 止) 截取(含头不含尾)、indexOf 查找子串位置(找不到返回 -1)、contains 判断是否包含、equals 比较内容、isEmpty/isBlank 判空、strip 去两端空白、split 按分隔符切开、String.join 反向拼合。判断字符串内容相等必须用 equals——用 == 比较的是两个引用是否指向同一个对象,内容相同的不同对象会返回 false,这是 Java 新手最著名的坑。

循环里反复拼接字符串时(比如拼一段长文本),每次 s += ... 都会新建对象,效率很差。这时该用 StringBuilder:它是可变的字符串容器,append 不断追加,最后 toString() 一次成型。String 的 + 拼接适合偶尔一两次,StringBuilder 适合批量拼接;另外还有 String.format("%s 今年 %d 岁", name, age) 这种格式化写法,适合拼固定模板。

示例

字符串的常用方法:

public class Main {
    public static void main(String[] args) {
        String text = "Hello, Java 世界";
        System.out.println("长度:" + text.length());
        System.out.println("第 1 个字符:" + text.charAt(0));
        System.out.println("前 5 个字符:" + text.substring(0, 5));
        System.out.println("Java 的位置:" + text.indexOf("Java"));
        System.out.println("包含「世界」?" + text.contains("世界"));
        System.out.println("转大写:" + text.toUpperCase());

        String csv = "苹果,香蕉,橙子";
        String[] fruits = csv.split(",");
        System.out.println("第二项:" + fruits[1]);
        System.out.println("重新拼合:" + String.join(" | ", fruits));
    }
}

== 与 equals 的区别,以及 String.format 格式化输出:

public class Main {
    public static void main(String[] args) {
        String a = new String("java");
        String b = new String("java");
        System.out.println("a == b:" + (a == b));
        System.out.println("a.equals(b):" + a.equals(b));

        String name = "王芳";
        int score = 92;
        System.out.println(String.format("%s 的成绩是 %d 分", name, score));
    }
}

循环拼接用 StringBuilder,最后一次转成 String:

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 5; i++) {
            sb.append("第").append(i).append("项");
            if (i < 5) {
                sb.append(",");
            }
        }
        String result = sb.toString();
        System.out.println(result);
        System.out.println("反转:" + new StringBuilder(result).reverse());
    }
}

常见坑

  • 用 == 比较字符串内容:字面量有时因常量池缓存碰巧相等,让 bug 时隐时现。比较内容永远用 equals;调用时把确定非空的放前面,"admin".equals(input) 不会空指针。
  • 忘记字符串不可变:写 text.toUpperCase(); 后直接用 text,内容毫无变化——方法返回的是新字符串,必须接住返回值 text = text.toUpperCase();。
  • substring 的下标越界:substring(0, 100) 作用在短字符串上直接抛异常。截取前确认长度,或先做 Math.min 保护。
  • 循环里用 + 拼长字符串:一万次拼接产生一万个中间对象,又慢又费内存。循环拼接一律换 StringBuilder。

小结

String 不可变,比较用 equals,常用方法围绕长度、截取、查找、判空;批量拼接用 StringBuilder,模板拼接用 String.format。下一节学习让程序按条件走不同路径:条件分支。