arrays.copyof核心是“创建新数组+复制数据”两阶段操作,根据newlength决定截断、补零或全量复制;newlength为负抛negativearraysizeexception,original为null则npe,始终浅拷贝且不支持偏移。

Arrays.copyOf 不是简单封装,它把“创建新数组 + 复制数据”两步收束成一个语义清晰的操作,既避免手动 new 的繁琐,又规避了直接赋值带来的引用共享风险。它的行为由 newLength 决定,不是无脑扩容,而是按需截断、补零或全量复制。
copyOf 的核心执行流程
该方法内部严格分两阶段执行:
- 先根据 original 类型和 newLength 创建新数组——基本类型走 new int[newLength] 等字面量方式,引用类型则通过 Array.newInstance() 动态生成;
- 再调用 System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)) 完成数据搬运。
整个过程不修改原数组,也不复用任何已有容器,每次调用都产生全新对象。这意味着即使 newLength 等于原长度,返回的也是内存地址不同的独立副本。
newLength 如何影响拷贝结果
这个参数直接控制最终数组形态,无需额外判断逻辑:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 等于 original.length:前 len 个元素完整复制,内容一致,但对象分离;
- 小于 original.length:只取前 newLength 个元素,相当于自动截断;
- 大于 original.length:前 original.length 个照搬,剩余位置填默认值(int→0,boolean→false,引用类型→null)。
例如 int[] src = {1,2,3};Arrays.copyOf(src, 5) 返回 [1,2,3,0,0];Arrays.copyOf(src, 2) 返回 [1,2]。
容易踩坑的关键细节
看似简单的方法,几个边界条件处理不当就会出错:
- newLength 为负数会立即抛 NegativeArraySizeException,不会等到 arraycopy 阶段;
- original 为 null 时直接 NPE,它不做空值防护,调用前必须自行判空;
- 泛型擦除后运行时类型丢失,跨类型转换(如 String[] → Object[])必须显式传入 newType 参数,否则类型不匹配;
- 拷贝始终从索引 0 开始,无法指定偏移——这是 copyOfRange 的职责,别混用。
性能与适用场景建议
copyOf 底层依赖 native 的 System.arraycopy,比纯 for 循环快一倍左右,但优势在中大数组(长度 > 16)才明显。小数据量(如配置数组、临时标记)可考虑直接赋值或 if 分支跳过;高频写场景(如 CopyOnWriteArrayList 的 add)依赖它完成“扩容+复制+赋值”原子链路,此时语义清晰比手写更可靠。
它不适合原地移位、错位覆盖或复用已有目标数组——这些得交给 System.arraycopy;也不适合深拷贝对象数组,因为所有内置拷贝均为浅拷贝,嵌套引用仍共享。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










