Arrays.copyOfRange是流式数组切片最直接安全的工具,支持左闭右开索引、自动新建数组、底层高效且适配各类协议偏移约定,但需前置边界校验防越界。

Arrays.copyOfRange 是处理大型流式数组数据切片最直接、安全且语义清晰的工具,尤其适合从连续字节流、缓冲区或长序列中按偏移量提取业务片段。
适用于流式场景的核心特性
它不依赖外部状态,仅凭原始数组和两个整数索引即可完成切片,天然契合流式数据“按位置提取”的需求:
- 自动创建新数组,无需预先分配目标空间,避免手动 new + 循环带来的冗余代码
- 底层调用
System.arraycopy,性能接近原生操作,对万级甚至十万级数组仍保持高效 - 索引语义统一为
[from, to)(左闭右开),与网络协议、内存布局、ByteBuffer.position() 等主流偏移约定一致 - 支持所有数组类型:
byte[](最常用)、int[]、String[]、自定义对象数组等
在流式数据包解析中的典型用法
面对 TCP 拆包、串口帧、二进制协议报文等场景,copyOfRange 常作为“第一道切片工序”:
- 提取固定字段:如 16 字节包头后第 4~7 字节为设备 ID →
Arrays.copyOfRange(packet, 20, 24) - 跳过头部取负载:跳过前 12 字节协议头,取后续全部有效载荷 →
Arrays.copyOfRange(packet, 12, packet.length) - 分块读取模拟:将一个大缓存数组按 1024 字节分片处理 →
Arrays.copyOfRange(buffer, offset, Math.min(offset + 1024, buffer.length))
必须做的边界防护与常见误用
流式数据长度不确定,越界是高频异常来源,不能只靠 try-catch:
立即学习“Java免费学习笔记(深入)”;
- 切片前务必校验:
if (packet.length - 避免硬编码
to = from + length却忽略to > original.length—— 此时会抛ArrayIndexOutOfBoundsException,而非静默截断 - 对空数组或零长度切片(
from == to)完全合法,返回空数组,可放心用于边界逻辑 - 注意:它只做浅拷贝。若数组元素是可变对象(如
ByteBuffer[]或byte[][]),新数组仍引用原对象,需额外深拷贝逻辑
配合 ByteBuffer 实现类型安全解析
切下来的 byte[] 片段需转为业务值,推荐封装组合使用:
- 整型字段(大端):
ByteBuffer.wrap(Arrays.copyOfRange(data, 8, 12)).order(BIG_ENDIAN).getInt() - 字符串字段(UTF-8,不含尾随 \0):
new String(Arrays.copyOfRange(data, 16, 32), UTF_8).trim() - 布尔标志位(第 0 字节 bit0):
(Arrays.copyOfRange(data, 0, 1)[0] & 0x01) != 0 - 建议封装成
readInt(data, offset)、readString(data, offset, len)等工具方法,隐藏切片细节,提升协议可读性


















