Arrays.toString 是日志输出数组最轻量稳妥的方式,但需判空、避多维、控大小、防敏感;null 数组会 NPE,二维数组须用 deepToString,大数组应截断或条件日志。

Arrays.toString 是日志中输出数组内容最轻量、最稳妥的方式,但高效不等于“无脑调用”——关键在于匹配场景、规避陷阱、控制开销。
日志中必须用 Arrays.toString,而不是直接打印数组
Java 原生数组没有重写 toString(),直接拼接或打印会输出类似 [I@4f9a33e6 的哈希码,完全无法用于排查。Arrays.toString() 自动格式化为 [1, 2, 3] 或 [true, false],语义清晰、结构统一。
- 所有 8 种原始类型(int[]、long[]、boolean[] 等)和 String[] 都开箱即用,无需装箱或流转换
- 空数组(
new int[0])安全返回[],不会异常也不会 null - 配合 SLF4J/Log4j 参数化日志,仅当日志级别启用时才执行转换,避免无效字符串构造
务必规避 null 和多维数组误用
null 数组传入 Arrays.toString() 会立即抛出 NullPointerException;二维及以上数组用 toString() 只显示内存地址,毫无调试价值。
- 判空推荐写法:
Arrays.toString(arr == null ? new int[0] : arr)(简单明确)或Optional.ofNullable(arr).map(Arrays::toString).orElse("null")(语义更严谨) - 二维数组(如
int[][])必须改用Arrays.deepToString(matrix),否则看到的是[[I@xxx, [I@yyy] - 注意:deepToString(null) 本身也会抛 NPE,不能替代判空
大数组与敏感数据的降级处理
百万级元素或含密码、token 的数组,全量 toString 会拖慢日志、撑爆磁盘,甚至泄露信息。
- 截断输出:
Arrays.toString(Arrays.copyOf(arr, Math.min(10, arr.length))),只看前若干项 - 条件包裹:
if (log.isDebugEnabled()) { log.debug("Detail: {}", Arrays.deepToString(data)); },生产环境自动跳过 - 敏感字段回避:
log.info("User IDs: {}", Arrays.toString(userIds))安全,但log.info("Raw credentials: {}", Arrays.toString(secrets))绝对禁止
调试与日志分离:别让日志逻辑污染调试习惯
日志里用 Arrays.toString 是标准动作;但在 IDE 调试时,更推荐悬停查看或 Evaluate Expression 实时调用,而非在代码里插一堆 System.out.println。
- Watches 面板添加
Arrays.toString(myArray),让关键数组始终可见 - 条件断点中结合
myArray != null && myArray.length > 50,再手动 deepToString 片段,避免卡死 - 单元测试中优先用
assertArrayEquals(expected, actual),而非依赖日志肉眼比对

















