文本块(Text Block)

Java 13 引入了文本块(Text Block),用三个双引号 """ 来表示多行字符串。终于不用再写一堆 \n 和拼接了。

我之前写 SQL 语句的时候,每次都要这样:

String sql = "SELECT id, name, email\n" +
             "FROM users\n" +
             "WHERE id = 1";

有了文本块,终于可以这样写了:

String sql = """
            SELECT id, name, email
            FROM users
            WHERE id = 1
            """;

今天我们来把文本块彻底讲透。

一、基础语法

1.1 基本使用

// 文本块以 """ 开始,以 """ 结束
String json = """
            {
                "name": "张三",
                "age": 25
            }
            """;

// 注意:三个双引号必须独占一行

1.2 与普通字符串的区别

// 普通字符串
String single = "Hello";              // 单行
String withNewline = "Hello\nWorld";  // 需要手动加 \n

// 文本块
String text = """
            Hello
            World
            """;  // 自动保留换行

二、自动去除缩进

2.1 缩进处理规则

文本块会自动去除"左侧公共缩进":

String code = """
            public void hello() {
                System.out.println("Hello");
            }
            """;

// JVM 会把前面的空格去掉:
// public void hello() {
//     System.out.println("Hello");
// }

2.2 行首缩进决定基准线

// 基准线是内容行的最小缩进
String s = """
          SELECT *                // 这行有 6 个空格
              FROM users          // 这行有 14 个空格
          WHERE id = 1            // 这行有 6 个空格
          """;

// 最小缩进是 6,所以 6 个空格被去掉
// 结果:
// SELECT *
//     FROM users
// WHERE id = 1

2.3 避免意外缩进

// ❌ 如果不希望有缩进,从行首开始写
String bad = """
            SELECT *
            FROM users
            """;

// ✅ 应该从行首开始
String good = """
SELECT *
FROM users
""";

三、转义字符

3.1 基本转义

String s = """
            Line 1\nLine 2\tTabbed
            """;

// \n → 换行
// \t → Tab

3.2 不必要的转义

// 在文本块中,某些字符不需要转义

// ✅ 单引号不需要转义
String s1 = """
            It's a fine day.
            """;

// ✅ 双引号在文本块中只需要单个(不用两个)
String s2 = """
            He said "Hello"
            """;

3.3 需要转义的情况

// 如果要结束文本块,需要转义结尾的 """
String s1 = """
            Hello \"""World          // 输出 Hello "World
            """;

// 三个点的连续引号需要转义
String s2 = """
            End of block \"""
            """;

3.4 \s 转义

// \s 表示单个空格,保持行末空格
String s = """
            SELECT *
            FROM users\s           // 保持末尾空格
            WHERE id = 1
            """;

四、格式化

4.1 formatted 方法

String name = "张三";
int age = 25;

String s = """
            Name: %s
            Age: %d
            """.formatted(name, age);

// 输出:
// Name: 张三
// Age: 25

4.2 使用占位符

String template = """
            <html>
                <body>
                    <h1>%s</h1>
                    <p>%s</p>
                </body>
            </html>
            """;

String html = template.formatted("Welcome", "Hello, World!");

4.3 localize 方法

// Java 21+ 支持
String s = """
            Hello, %s!
            """.localized();

// 可以配合 Locale 使用
String localized = """
            Greeting: %s
            """.formatted("Hello")
              .transform(s -> s.toUpperCase());

五、【直观类比】

【直观类比】

文本块就像 Markdown 代码块:

Markdown:

代码内容


Java 文本块:

""" 代码内容 """


唯一区别是 Java 的 `"""` 要独占一行。

## 六、实用场景

### 6.1 JSON

```java
String json = """
            {
                "id": 1,
                "name": "张三",
                "email": "zhang@example.com",
                "active": true
            }
            """;

6.2 SQL

String sql = """
            SELECT u.id, u.name, o.total
            FROM users u
            LEFT JOIN orders o ON u.id = o.user_id
            WHERE u.created_at > '2024-01-01'
            ORDER BY o.total DESC
            LIMIT 100
            """;

6.3 HTML/XML

String html = """
            <!DOCTYPE html>
            <html>
            <head>
                <title>My Page</title>
            </head>
            <body>
                <h1>Hello</h1>
            </body>
            </html>
            """;

6.4 正则表达式

String pattern = """
            ^\d{3}    # 区号
            -         # 分隔符
            \d{4}     # 前缀
            -         # 分隔符
            \d{4}$    # 后缀
            """;
Pattern p = Pattern.compile(pattern, Pattern.COMMENTS);

七、注意事项

7.1 行末空格

// ❌ 行末的空格会被保留
String s = """
            SELECT *     
            FROM users    
            """;

// 建议使用 trim() 或 \s
String s2 = """
            SELECT *
            FROM users
            """.trim();

7.2 性能

// 文本块在编译时处理,不是运行时拼接
// 性能和普通字符串一样
String s = """
            SELECT * FROM users
            """;  // 编译后就是 "SELECT * FROM users\n"

八、面试追问链

第一层:基础概念

面试官问:"文本块是什么?"

Java 13 引入的特性,用 """ 表示多行字符串,自动处理换行和缩进,比普通字符串更易读。

第二层:缩进规则

面试官问:"文本块的缩进是怎么处理的?"

JVM 自动去除内容行的左侧公共缩进,以最左边的非空格字符为基准。

第三层:实际应用

面试官问:"你在项目里用过文本块吗?"

可以提到用于 SQL、JSON、HTML 等多行字符串场景,避免大量 \n 和字符串拼接。

【学习小结】

  • 文本块用 """ 表示多行字符串
  • 自动去除左侧公共缩进
  • 支持 \n\t 等转义字符
  • 支持 formatted() 格式化
  • 适合 SQL、JSON、HTML 等场景