方法定义

public synchronized void setLength(int newLength)
  • 参数newLength - 新的字符序列长度(必须 ≥ 0)
  • 异常
    • IndexOutOfBoundsException:如果 newLength < 0
  • 线程安全:使用 synchronized 修饰(多线程安全)

功能说明

设置字符序列的新长度,主要实现两种功能:

  1. 扩展长度:用空字符(\u0000)填充新增位置
  2. 截断长度:丢弃超出 newLength 的字符
  3. 缓冲区复用:重置长度而不新建对象

示例代码

// 示例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 + "|"); // 输出 "||"(空字符串)

使用技巧

  1. 快速清空缓冲区(替代 new StringBuffer()):
    StringBuffer buffer = new StringBuffer();
    // 重复使用
    buffer.append("Data");
    buffer.setLength(0); // 清空内容,保留底层数组
    
  2. 填充固定长度字符串
    StringBuffer sb = new StringBuffer();
    sb.setLength(5); // 预先分配5个空字符
    sb.replace(0, 5, "12345"); // 快速填充
    

常见错误

  1. 负长度设置
    sb.setLength(-1); // 抛出 IndexOutOfBoundsException
    
  2. 误解缓冲区容量
    StringBuffer sb = new StringBuffer(100); // 容量=100
    sb.setLength(50);  // 设置的是长度,容量仍为100
    System.out.println(sb.capacity()); // 输出 100
    

注意事项

  1. 空字符填充:扩展时新增位置用 \u0000 填充
    • 打印时显示为空格,但实际是不同字符
  2. 不可逆操作:截断后数据永久丢失
    sb.append("Important Data");
    sb.setLength(5); // 数据被永久截断
    
  3. 长度 vs 容量
    • length():当前存储的字符数
    • capacity():当前分配的存储空间大小

性能优化

  1. 对象复用:在循环中重用缓冲区
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < 1000; i++) {
        sb.append("data"); 
        process(sb);
        sb.setLength(0); // 比 new StringBuffer() 高效90%
    }
    
  2. 避免过度扩展:合理设置初始容量
    // 预估最大长度500
    StringBuffer sb = new StringBuffer(500);
    

总结

核心功能 关键点
长度扩展 新增位置用空字符(\u0000)填充
长度截断 永久丢弃超出部分的字符
缓冲区复用 setLength(0) 比新建对象快10倍(避免内存分配和GC)
线程安全 多线程操作首选 StringBuffer,单线程用 StringBuilder 更高效
容量管理 setLength() 只改长度,不改容量;用 ensureCapacity() 管理空间

最佳实践

  1. 循环操作必用setLength(0) 复用缓冲区
    // 高效模板
    StringBuffer reusable = new StringBuffer();
    while (condition) {
        reusable.append(...);
        process(reusable);
        reusable.setLength(0); // 关键!
    }
    
  2. 安全截断:先检查再截断
    if (newLength <= sb.length()) {
        sb.setLength(newLength);
    }
    
  3. 长度校正:处理外部输入时验证长度
    int userInputLength = getUserInput();
    if (userInputLength >= 0) {
        sb.setLength(userInputLength);
    }
    

⚠️ 关键警告
截断操作不可逆!确保不再需要被丢弃的数据。
扩展时空字符可能影响字符串比较(equals()\u0000 不匹配)。