
本文详解 Java 中 for 循环误打印数组对象地址(如 [I@5a07e868)的根本原因,阐明 foreach 自动解引用的机制,并提供正确遍历数组的写法、常见误区及调试建议。
本文详解 java 中 `for` 循环误打印数组对象地址(如 `[i@5a07e868`)的根本原因,阐明 `foreach` 自动解引用的机制,并提供正确遍历数组的写法、常见误区及调试建议。
在 Java 中,for 循环与增强型 for 循环(即 foreach)虽然都能遍历数组,但二者语义和使用方式存在本质区别——关键在于操作对象是“数组本身”还是“数组中的单个元素”。
观察原始代码中的问题段落:
for (int i = 0; i < z.length; i++) {
System.out.println(z); // ❌ 错误:z 是整个 int[] 数组引用
}此处 z 是一个 int[] 类型的变量,代表数组对象的引用。当直接对数组调用 System.out.println(z) 时,JVM 实际执行的是 z.toString()。由于 int[] 是 JVM 内置的原生数组类型,它并未重写 Object.toString() 方法,因此默认输出格式为:
[类型码@十六进制哈希值
其中 [I 表示“一维 int 数组”([ 表示数组,I 是 int 的 JVM 类型签名),@5a07e868 是该数组对象的哈希码(非内存地址,但常被误称为“地址”)。这并非真正的内存地址,而是 Object.hashCode() 的默认实现结果。
立即学习“Java免费学习笔记(深入)”;
而 foreach 循环:
for (int i : z) {
System.out.println(i); // ✅ 正确:i 是 int 类型的每个元素值
}其语法糖本质等价于:
for (int idx = 0; idx < z.length; idx++) {
int i = z[idx]; // 自动取值,解引用
System.out.println(i);
}也就是说,foreach 隐式完成了 z[idx] 的索引访问,将每个 int 值赋给循环变量 i,而 int 是基本类型,println(int) 会直接输出数值。
✅ 正确的普通 for 循环写法应显式使用下标访问元素:
int[] z = {4, 6, 8, 10, 12, 14};
for (int i = 0; i < z.length; i++) {
System.out.println(z[i]); // 输出:4, 6, 8, ...
}⚠️ 注意事项:
- 不要混淆 z(数组引用)与 z[i](数组元素);
- 对于对象数组(如 String[]),若未重写 toString(),System.out.println(arr[i]) 仍可能输出类似 ClassName@hash,此时需确保元素类已正确定义 toString();
- 使用 Arrays.toString(z) 可一键打印整个数组内容(推荐用于调试):
import java.util.Arrays; // ... System.out.println(Arrays.toString(z)); // 输出:[4, 6, 8, 10, 12, 14]
总结:foreach 提供了更安全、简洁的元素级遍历抽象,避免手动索引错误;而传统 for 循环需开发者明确区分“容器”与“内容”。理解 z 和 z[i] 的类型差异,是避免此类输出异常的核心前提。










