<think>我们正在讨论Java字符串占位符。在Java中,字符串占位符通常指的是在字符串中预留位置,然后在运行时用实际值替换这些位置。常见的实现方式有:
1. 使用`String.format()`方法,类似于C语言中的`printf`。
2. 使用`MessageFormat`类,它提供更复杂的占位功能,包括格式化数字、日期等。
3. 从Java 15开始,文本块(Text Blocks)也可以结合占位符使用,但通常还是用前两种方式。
下面分别给出示例:
### 1. 使用`String.format()`
`String.format()`使用格式说明符,如`%s`表示字符串,`%d`表示整数等。
示例代码:
```java
public class StringFormatExample {
public static void main(String[] args) {
String name = "Alice";
int age = 25;
// 使用占位符 %s 和 %d
String formattedString = String.format("姓名: %s, 年龄: %d", name, age);
System.out.println(formattedString);
}
}
```
输出:
```
姓名: Alice, 年龄: 25
```
### 2. 使用`MessageFormat`
`MessageFormat`提供了更强大的功能,比如可以处理复数、日期等,并且占位符使用`{0}`, `{1}`等索引。
示例代码:
```java
import java.text.MessageFormat;
public class MessageFormatExample {
public static void main(String[] args) {
String name = "Bob";
int score = 90;
// 使用占位符 {0} 和 {1}
String formattedString = MessageFormat.format("姓名: {0}, 分数: {1}", name, score);
System.out.println(formattedString);
}
}
```
输出:
```
姓名: Bob, 分数: 90
```
### 3. 文本块(Text Blocks)与占位符结合
文本块(Java 15及以上)可以用于多行字符串,但本身不提供占位符功能,我们可以结合`String.format()`使用。
示例代码:
```java
public class TextBlockExample {
public static void main(String[] args) {
String item = "Apple";
double price = 2.5;
// 文本块
String template = """
商品: %s
价格: %.2f
""";
String formattedString = String.format(template, item, price);
System.out.println(formattedString);
}
}
```
输出:
```
商品: Apple
价格: 2.50
```
### 注意事项
- 在`String.format()`中,格式说明符需要与参数类型匹配,否则会抛出异常。
- `MessageFormat`占位符中的索引从0开始,并且可以重复使用同一个索引。
- 文本块在定义多行字符串时非常方便,但占位替换仍需借助其他方法。
### 相关问题
1. 在Java中,除了`String.format()`和`MessageFormat`,还有哪些方式可以实现字符串占位符功能?
2. 如何在使用`String.format()`时处理日期和时间的格式化?
3. `MessageFormat`在处理复数形式(如英文中的单复数)时有什么特殊用法?</think>### Java字符串占位符详解
在Java中,字符串占位符用于动态构建字符串,主要有三种实现方式:
#### 1. `String.format()`(最常用)
**语法**:`String.format("模板", 参数1, 参数2...)`
**占位符**:
- `%s`:字符串
- `%d`:整数
- `%f`:浮点数
- `%.2f`:保留两位小数
- `%n`:换行符
**示例**:
```java
String name = "张三";
int age = 30;
double salary = 12000.456;
// 基础用法
String s1 = String.format("姓名: %s, 年龄: %d", name, age);
// 结果: "姓名: 张三, 年龄: 30"
// 数字格式化
String s2 = String.format("薪资: %.2f 元", salary);
// 结果: "薪资: 12000.46 元"
// 多参数混合
String s3 = String.format("%s今年%d岁,收入:¥%.2f%n", name, age, salary);
// 结果: "张三今年30岁,收入:¥12000.46"(末尾换行)
```
#### 2. `MessageFormat`(支持复杂格式化)
**特点**:支持索引化参数和数据类型自动转换
```java
import java.text.MessageFormat;
String template = "姓名: {0}, 年龄: {1}, 出生日期: {2, date}";
Object[] params = {"李四", 25, new java.util.Date()};
String result = MessageFormat.format(template, params);
// 结果示例: "姓名: 李四, 年龄: 25, 出生日期: 2023/10/26"
```
#### 3. 文本块(Java 15+ 多行文本)
```java
String jsonTemplate = """
{
"name": "%s",
"age": %d,
"salary": %.1f
}
""";
System.out.printf(jsonTemplate, "王五", 28, 15000.0);
```
### 🔧 使用场景对比
| **方法** | **适用场景** | **优势** |
|------------------|-------------------------------------|-----------------------------|
| `String.format` | 简单占位替换 | 语法简洁,类似C语言`printf` |
| `MessageFormat` | 国际化、日期/数字复杂格式化 | 支持本地化,参数可重用 |
| 文本块+`format` | 多行文本模板(JSON/SQL等) | 保持原始格式,易读性高 |
### ⚠️ 注意事项
1. 参数类型必须匹配占位符,否则抛出`IllegalFormatException`
2. 索引从0开始:`%1$s`表示第一个字符串参数(显式指定参数位置)
3. 性能敏感场景建议用`StringBuilder`手动拼接
### 相关问题
1. Java中如何实现带颜色输出的格式化字符串?
2. 在Spring框架中如何结合`@Value`注解使用占位符?
3. 如何通过`Formatter`类实现自定义占位符解析?
4. 字符串模板(Java 21预览特性)与占位符有何区别?