1. 简介

String 是 Java 中最核心的类之一,我们在之前的 String 相关系列教程 中已经对它做了大量介绍。

本文将重点讲解 Java 中 String 的初始化方式,包括声明与赋值的区别、字符串池机制、null 值处理等内容。

2. String 的创建方式

在 Java 中,创建 String 有两种常见方式:

  • 使用 new 关键字
  • 使用字符串字面量(literal)
String usingNew = new String("baeldung");
String usingLiteral = "baeldung";

✅ 推荐使用字面量方式,更简洁高效。
⚠️ 使用 new 会强制在堆中创建新对象,不推荐除非有特殊需求。

3. 仅声明 String 变量

我们可以在不赋值的情况下声明 String 变量:

public class StringInitialization {

    String fieldString; // 成员变量自动初始化为 null

    void printDeclaredOnlyString() {
        String localVarString; // 局部变量未初始化
        
        // System.out.println(localVarString); -> 编译错误
        System.out.println(fieldString); // 输出 null
    }
}

📌 要点总结:

  • ✅ 成员变量自动初始化为 null
  • ❌ 局部变量必须显式赋值后才能使用
  • 如果局部变量赋值为 null,它与未赋值的成员变量在值上是等价的
String localVarString = null;
assertEquals(fieldString, localVarString); // 成功通过

4. 使用字面量初始化 String

使用相同字面量创建多个 String 变量时,JVM 会利用字符串池优化:

String literalOne = "Baeldung";
String literalTwo = "Baeldung";

比较引用地址:

assertTrue(literalOne == literalTwo); // ✅ 成功通过

📌 原理说明:

  • 字符串池中只会保存一份相同的字符串字面量
  • 第一个赋值会将字符串放入池中,后续相同字面量会复用

5. 使用 new 初始化 String

使用 new 关键字创建 String 会绕过字符串池:

String newStringOne = new String("Baeldung");
String newStringTwo = new String("Baeldung");

虽然内容相同,但地址不同:

assertFalse(newStringOne == newStringTwo); // ✅ 成功通过

📌 要点总结:

  • new String("xxx") 总是创建新对象
  • 适合需要多个不同引用但内容相同字符串的场景(极少)

6. 空字符串初始化

创建空字符串有三种常见方式:

String emptyLiteral = "";                  // 字面量,放入池中
String emptyNewString = new String("");    // new,不放入池中
String emptyNewStringTwo = new String();   // new,不放入池中

📌 比较结果:

assertFalse(emptyLiteral == emptyNewString);     // 地址不同
assertFalse(emptyLiteral == emptyNewStringTwo);  // 地址不同
assertFalse(emptyNewString == emptyNewStringTwo);// 地址不同
assertEquals(emptyLiteral, emptyNewString);      // 内容相同
assertEquals(emptyNewString, emptyNewStringTwo); // 内容相同

✅ 所有空字符串内容一致,但引用不同(除非是字面量复用)

7. null 值处理

声明一个 null String:

String nullValue = null;

打印时输出的是 "null",但这只是 Java 的默认处理方式。

📌 为什么打印 null 会输出 "null"?

查看 PrintStream.println(Object) 源码:

public void println(Object x) {
    String s = String.valueOf(x);
    ...
}

再看 String.valueOf(Object)

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

✅ 所以,打印 null 实际上是调用 String.valueOf() 的结果,而不是 null 本身。

⚠️ 如果对 null 调用方法,会抛出 NullPointerException,例如:

nullValue.length(); // 抛出 NullPointerException

8. 总结

本文详细讲解了 Java 中 String 的初始化方式,包括:

初始化方式 是否入池 是否创建新对象 默认值 推荐程度
字面量 ✅ 是 ❌ 否 ✅ 强烈推荐
new String("xxx") ❌ 否 ✅ 是 ⚠️ 谨慎使用
null - - null ✅ 合理使用
空字符串字面量 ✅ 是 ❌ 否 "" ✅ 推荐

📌 最佳实践建议:

  • ✅ 优先使用字面量初始化字符串
  • ❌ 避免不必要的 new String("xxx")
  • ✅ 理解 null 与空字符串的区别
  • ✅ 理解字符串池机制,避免踩坑

所有示例代码均可在 GitHub 仓库 获取。


原始标题:String Initialization in Java