1. 方法定义

public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

2. 功能说明

参数 作用
srcBegin 源字符串起始索引(包含)
srcEnd 源字符串结束索引(不包含)
dst 目标字符数组
dstBegin 目标数组的起始写入位置

核心特性

  • 高效内存复制:直接操作字符数组,避免创建中间字符串对象
  • 区间控制:复制 [srcBegin, srcEnd) 的字符到目标数组
  • 原地修改:直接修改传入的 char[] 数组内容

3. 示例代码

StringBuffer sb = new StringBuffer("Hello, 世界!");

// 创建目标数组(长度需足够)
char[] buffer = new char[5];

// 复制索引[7,12)的字符 → "世界"
sb.getChars(7, 12, buffer, 0);

// 验证结果
System.out.println(Arrays.toString(buffer)); 
// 输出: [世, 界, \u0000, \u0000, \u0000] (未填充部分为默认值)

4. 使用技巧

  1. 部分字符串提取
    // 提取后4字符
    char[] last4 = new char[4];
    sb.getChars(sb.length()-4, sb.length(), last4, 0);
    
  2. 组合多个子串
    char[] combined = new char[10];
    sb.getChars(0, 5, combined, 0);    // 复制前5字符
    sb.getChars(7, 9, combined, 5);    // 后续字符从索引5开始
    
  3. 字符串预处理
    char[] temp = new char[sb.length()];
    sb.getChars(0, sb.length(), temp, 0);
    Arrays.sort(temp);  // 直接操作字符数组排序
    

5. 常见错误

  1. 索引越界
    // 源索引超出范围
    sb.getChars(0, 20, buffer, 0); // StringIndexOutOfBoundsException
    
    // 目标索引超出数组长度
    char[] small = new char[3];
    sb.getChars(0, 5, small, 0); // IndexOutOfBoundsException
    
  2. 区间无效
    // srcBegin > srcEnd
    sb.getChars(5, 2, buffer, 0); // StringIndexOutOfBoundsException
    
  3. 空指针异常
    char[] uninit = null;
    sb.getChars(0, 3, uninit, 0); // NullPointerException
    

6. 注意事项

  1. 数组长度验证
    目标数组必须满足:dstBegin + (srcEnd - srcBegin) <= dst.length
    // 安全检查示例
    int copyLen = srcEnd - srcBegin;
    if (dstBegin + copyLen > dst.length) {
        throw new IndexOutOfBoundsException("目标数组空间不足");
    }
    
  2. 多字节字符处理
    正确处理Unicode字符(如中文):
    StringBuffer sb = new StringBuffer("A字");
    char[] buf = new char[2];
    sb.getChars(0, 3, buf, 0); // 正确:'A'(1字符)+ '字'(2字符)
    
  3. 目标数组内容覆盖
    不会自动清空数组原有数据:
    char[] data = {'A','B','C','D'};
    sb.getChars(0, 2, data, 1); 
    // 结果: ['A', 'H', 'e', 'D'] (原'B','C'被覆盖)
    

7. 最佳实践与性能优化

  1. 复用字符数组(减少GC压力)
    // 初始化大数组池
    char[][] bufferPool = new char[10][1024];
    int currentBuffer = 0;
    
    void processString(StringBuffer sb) {
        char[] buf = bufferPool[currentBuffer];
        int len = sb.length();
        if (buf.length < len) buf = new char[len];
    
        sb.getChars(0, len, buf, 0);
        // 处理逻辑...
    
        bufferPool[currentBuffer] = buf;
        currentBuffer = (currentBuffer + 1) % 10;
    }
    
  2. 零拷贝处理
    结合NIO进行高效I/O操作:
    CharBuffer charBuffer = CharBuffer.allocate(1024);
    sb.getChars(0, sb.length(), charBuffer.array(), 0);
    FileChannel.write(ByteBuffer.wrap(charBuffer.array()));
    
  3. 批量操作优化
    替代多次charAt()调用:
    // ❌ 低效方式
    for (int i = 0; i < sb.length(); i++) {
        char c = sb.charAt(i);  // 每次调用都有边界检查
    }
    
    // ✅ 高效方式
    char[] temp = new char[sb.length()];
    sb.getChars(0, sb.length(), temp, 0);
    for (char c : temp) { ... }
    
  4. 内存敏感场景优化
    精确分配数组大小:
    int start = 5, end = 15;
    char[] exactSize = new char[end - start]; // 精确分配
    sb.getChars(start, end, exactSize, 0);
    

总结

关键点 操作建议
核心价值 高性能字符复制,避免创建中间String对象
索引安全 始终校验:0 ≤ srcBegin ≤ srcEnd ≤ length()dstBegin + len ≤ dst.length
内存优化 复用char[]数组,精确分配空间
性能优势 替代循环charAt(),尤其适合大文本处理
特殊场景 与NIO/文件操作结合实现零拷贝