
本文解析java中普通for循环误打印数组对象引用而非元素值的根本原因,并通过代码对比阐明两种循环的语义差异及正确用法。
本文解析java中普通for循环误打印数组对象引用而非元素值的根本原因,并通过代码对比阐明两种循环的语义差异及正确用法。
在Java中,for循环与增强型for循环(即for-each)虽然都可用于遍历数组,但二者在语法语义和访问目标上存在本质区别——这直接导致了初学者常见的“打印出[I@xxxxxx地址而非实际数值”的困惑。
问题核心在于:普通for循环本身不自动解引用,它只提供索引;而for-each循环隐式完成索引访问与元素提取。
回顾原始代码片段:
int z[] = Multi(ar);
for (int i = 0; i < z.length; i++) {
System.out.println(z); // ❌ 错误:打印的是整个数组对象(引用)
}
for (int i : z) {
System.out.println(i); // ✅ 正确:i 是数组中每个 int 元素的副本
}第一段循环中,System.out.println(z) 实际输出的是 z 这个数组对象的默认字符串表示。由于 int[] 是对象(属于 Object 子类),其未重写 toString() 方法,因此 JVM 调用父类 Object.toString(),返回格式为 [I@
立即学习“Java免费学习笔记(深入)”;
而第二段 for (int i : z) 是语法糖,编译器将其翻译为等效的传统循环:
for (int idx = 0; idx < z.length; idx++) {
int i = z[idx]; // ✅ 显式通过索引取值
System.out.println(i);
}因此,i 是 z[idx] 的值拷贝(对基本类型是值本身,对引用类型是引用副本),自然输出 4, 6, 8 等整数值。
✅ 正确使用普通for循环遍历并打印元素,必须显式使用下标访问:
for (int i = 0; i < z.length; i++) {
System.out.println(z[i]); // ✅ 输出元素值
}⚠️ 注意事项:
- for-each 循环无法获取当前索引(除非额外声明计数器变量),也不支持反向遍历或跳跃访问;
- 对于需要修改数组元素的场景,for-each 中的变量是副本,i = 100; 不会改变原数组内容;若需修改,必须使用传统for循环配合下标赋值(如 z[i] = 100;);
- 数组长度应始终用 arr.length(无括号),不可写作 arr.length()(这是Collection接口的方法)。
总结:所谓“for给地址、for-each给元素”,实为对循环变量理解偏差所致。关键不在循环类型本身,而在于你究竟把什么传给了println()——是数组引用 z,还是经由索引/迭代器取出的元素 z[i] 或 i。掌握这一底层逻辑,即可避免绝大多数数组遍历误用问题。










