Arrays.toString不能正确输出多维数组内容,因其仅遍历第一层,子数组显示为内存地址;应使用Arrays.deepToString()递归展开并安全处理null、多维及混合类型。

Arrays.toString 方法不能正确输出多维数组内容——它只展开第一层,内部子数组仍显示为内存地址(如 [[I@1b6d3586, [I@4554617c]),完全不可读。真正想看清结构,必须换用 Arrays.deepToString() 或其他适配方案。
为什么 Arrays.toString 对多维数组无效
Java 中的多维数组本质是“数组的数组”,而 Arrays.toString() 设计上仅做一层遍历:它把每个子数组当作普通对象,调用其默认 toString(),结果就是类名加哈希码。这不是 bug,而是明确的行为边界。
- 对
int[][] arr = {{1,2}, {3,4}};,Arrays.toString(arr)输出类似[[I@xxx, [I@yyy] - 即使子数组内容相同,只要不是同一引用,地址也不同,无法判断实际数据
- 该方法不递归、不防护 null、不处理嵌套逻辑,属于轻量级一维专用工具
首选替代:Arrays.deepToString()
这是 JDK 内置的、专为多维数组设计的解决方案,能递归展开所有层级,并安全处理常见边界情况。
- 支持任意维度:二维、三维、甚至
int[][][][]都可直接传入 - 自动识别并格式化基本类型数组(
int[])、对象数组(String[][])、混合型(Object[]含int[]和null) - 遇到
null元素输出字符串"null",不会抛NullPointerException - 输出符合 Java 习惯:方括号嵌套、逗号分隔、空格对齐,例如
[[1, 2], [3, 4, 5]]
自定义格式或受限环境下的手动方案
当需要去掉空格、改用竖线分隔、或项目禁用 Arrays 工具类时,可借助流式处理或 StringBuilder 手动拼接。
- 一维数组简单定制:
String.format("[%s]", String.join(" | ", Arrays.stream(arr).map(String::valueOf).toArray(String[]::new))) - 基本类型转字符串数组再处理:如
int[]需先用Arrays.stream(arr).mapToObj(String::valueOf).toArray() - 多维数组无法靠 Stream 简单复现
deepToString行为,此时应避免手写递归(易错),优先考虑 Jackson/Gson 序列化
调试与生产中的实用提醒
打印数组不只是语法问题,还涉及可观测性与安全性。
- 日志中建议统一用
log.debug("data: {}", Arrays.deepToString(arr)),比悬停变量更可靠 - 数组为
null时,Arrays.deepToString(null)会直接抛空指针,务必提前判空 - 超大数组(如百万级)慎用,可截断:
Arrays.deepToString(Arrays.copyOf(arr, Math.min(100, arr.length))) - 含敏感字段时禁止直接打印,应脱敏或跳过

















