实战复盘:Java String 新手最全避坑手册|常量池、相等判断、拼接原理

29 阅读4分钟

基础不牢,地动山摇。很多时候我们虽然写了很多年的代码,回过头来突然发现很多基础知识已经遗忘到脑后了,今天我们一起来复习一下 Java String,彻底夯实Java基础:

为什么字符串对比不能用 ==?

为什么明明内容一样,结果却是false?

字符串拼接到底有什么坑?

每个知识点都附带的有示例,也特别适合新手宝子们学习记忆。


一、最大误区:String相等用 == 判断

这是新手100%必踩的坑,也是面试必考基础题。

核心结论

  • ==:比较 内存引用地址
  • equals() :比较 字符串内容

错误Demo(新手常写)

public class StringTest {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = "hello";
        System.out.println(s1 == s2); // false
    }
}

正确写法

System.out.println(s1.equals(s2)); // true

新手口诀:所有字符串内容对比,一律用equals。


二、常量池误区:为什么有的字符串==是true?

Java存在 字符串常量池,目的是复用字符串、节省内存。

并非所有字符串都存储在常量池中。字面量(如 "abc")直接双引号创建的字符串,会进入常量池复用;new出来的(new String("abc") )字符串,永远在堆内存新建对象。

Demo演示

String a = "test";
String b = "test";
// 常量池复用,同一地址
System.out.println(a == b); // true

String c = new String("test");
// new对象,新地址
System.out.println(a == c); // false

关键点:String s = new String("test") 这一行代码,可能创建1个或2个对象:如果常量池中没有 "test",则会先在常量池创建,再在堆中创建。

核心总结:

双引号赋值:走常量池复用

new String:强制新建对象


三、字符串拼接误区:循环里直接+拼接

新手写循环拼接字符串,最爱直接用 + ,这是性能大坑。在循环中使用 + 拼接字符串,每次都会创建一个新的 StringBuilder 对象和最终的 String 对象,导致性能低下和内存浪费

错误Demo(性能极差)

String res = "";
for (int i = 0; i < 1000; i++) {
    res += i;
}

原理:每一次+拼接,都会新建String对象,循环越多,内存浪费越严重。

正确写法(循环拼接必用)

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String res = sb.toString();

铁律:

  • 少量固定拼接:直接 + 没问题
  • 循环动态拼接:必须用StringBuilder

四、空指针误区:字符串判空写法颠倒

新手极易出现的 NullPointerException 空指针BUG。

危险写法(必报错)

String name = null;
if (name.equals("admin")) {
    // 空指针异常!
}

安全写法

if ("admin".equals(name)) {

}

原理:常量字符串永远不为null,彻底规避空指针。


五、空字符串和null误区(90%新手分不清)

很多新手认为 null 和 "" 是空一样,完全错误!

  • null:没有对象,空引用
  • "" :空字符串,是一个真实存在的对象,只是内容为空

完整安全判空Demo(开发通用模板)

public static boolean isEmpty(String str){
    return str == null || "".equals(str.trim());
}

六、String不可变误区:到底什么是不可变?

新手误解:以为字符串变量赋值改变了,就是内容变了。

正确概念:String 对象一旦创建,String 内容不可变,变量引用可以变。所有看似修改的操作,如 concat()、replace()、toLowerCase() 等,都会返回一个新的 String 对象,原对象保持不变。

Demo演示

String s = "hello";
s = "world";

不是 hello 变成了 world!

是 s变量指向了新的字符串对象,旧的hello内容永远不会被修改。

不可变好处:安全、可缓存、常量池复用、多线程安全。


终极String总结(直接背)

  1. 字符串内容对比,只用equals,禁止==

  2. 双引号走常量池,new 永远新建对象

  3. 循环拼接必须用 StringBuilder

  4. 常量在前、变量在后,规避空指针

  5. null是空对象,""是空内容,完全不同

  6. String内容不可变,赋值只是更换引用


Java基础看似简单,实则处处是坑。很多线上BUG、面试挂科,都是因为基础模糊。

欢迎点赞收藏关注,后续持续更新【后端基础】:Java语法、集合、异常、线程、MySQL基础、SpringBoot入门,全部新手友好、带Demo、可落地、可面试。