方法定义
public synchronized void setLength(int newLength)
- 参数:
newLength- 新的字符序列长度(必须 ≥ 0) - 异常:
IndexOutOfBoundsException:如果newLength < 0
- 线程安全:使用
synchronized修饰(多线程安全)
功能说明
设置字符序列的新长度,主要实现两种功能:
- 扩展长度:用空字符(
\u0000)填充新增位置 - 截断长度:丢弃超出
newLength的字符 - 缓冲区复用:重置长度而不新建对象
示例代码
// 示例1:扩展长度
StringBuffer sb = new StringBuffer("Hello");
sb.setLength(8); // 扩展长度
System.out.println(sb); // 输出 "Hello "(末尾3个空字符)
System.out.println((int)sb.charAt(6)); // 输出 0(空字符的ASCII值)
// 示例2:截断字符串
sb.setLength(3); // 截断
System.out.println(sb); // 输出 "Hel"
// 示例3:清空缓冲区
sb.setLength(0); // 清空
System.out.println("|" + sb + "|"); // 输出 "||"(空字符串)
使用技巧
- 快速清空缓冲区(替代
new StringBuffer()):StringBuffer buffer = new StringBuffer(); // 重复使用 buffer.append("Data"); buffer.setLength(0); // 清空内容,保留底层数组 - 填充固定长度字符串:
StringBuffer sb = new StringBuffer(); sb.setLength(5); // 预先分配5个空字符 sb.replace(0, 5, "12345"); // 快速填充
常见错误
- 负长度设置:
sb.setLength(-1); // 抛出 IndexOutOfBoundsException - 误解缓冲区容量:
StringBuffer sb = new StringBuffer(100); // 容量=100 sb.setLength(50); // 设置的是长度,容量仍为100 System.out.println(sb.capacity()); // 输出 100
注意事项
- 空字符填充:扩展时新增位置用
\u0000填充- 打印时显示为空格,但实际是不同字符
- 不可逆操作:截断后数据永久丢失
sb.append("Important Data"); sb.setLength(5); // 数据被永久截断 - 长度 vs 容量:
length():当前存储的字符数capacity():当前分配的存储空间大小
性能优化
- 对象复用:在循环中重用缓冲区
StringBuffer sb = new StringBuffer(); for (int i = 0; i < 1000; i++) { sb.append("data"); process(sb); sb.setLength(0); // 比 new StringBuffer() 高效90% } - 避免过度扩展:合理设置初始容量
// 预估最大长度500 StringBuffer sb = new StringBuffer(500);
总结
| 核心功能 | 关键点 |
|---|---|
| 长度扩展 | 新增位置用空字符(\u0000)填充 |
| 长度截断 | 永久丢弃超出部分的字符 |
| 缓冲区复用 | setLength(0) 比新建对象快10倍(避免内存分配和GC) |
| 线程安全 | 多线程操作首选 StringBuffer,单线程用 StringBuilder 更高效 |
| 容量管理 | setLength() 只改长度,不改容量;用 ensureCapacity() 管理空间 |
最佳实践:
- 循环操作必用:
setLength(0)复用缓冲区// 高效模板 StringBuffer reusable = new StringBuffer(); while (condition) { reusable.append(...); process(reusable); reusable.setLength(0); // 关键! } - 安全截断:先检查再截断
if (newLength <= sb.length()) { sb.setLength(newLength); } - 长度校正:处理外部输入时验证长度
int userInputLength = getUserInput(); if (userInputLength >= 0) { sb.setLength(userInputLength); }
⚠️ 关键警告:
截断操作不可逆!确保不再需要被丢弃的数据。
扩展时空字符可能影响字符串比较(equals()和\u0000不匹配)。