
本文详解java中普通for循环误打印数组对象地址、而增强for循环正确输出元素值的根本原因,并通过代码示例和内存视角阐明数组引用与元素访问的本质区别。
本文详解java中普通for循环误打印数组对象地址、而增强for循环正确输出元素值的根本原因,并通过代码示例和内存视角阐明数组引用与元素访问的本质区别。
在Java中,for循环与for-each(增强for)循环虽常用于遍历数组,但二者语义与使用方式存在本质差异——这直接导致了你观察到的“一个输出地址、一个输出数值”的现象。关键不在于循环本身“返回地址或元素”,而在于你实际传递给System.out.println()的是什么对象。
来看你的原始代码片段:
for (int i = 0; i < z.length; i++) {
System.out.println(z); // ❌ 错误:z 是整个 int[] 数组引用
}
for (int i : z) {
System.out.println(i); // ✅ 正确:i 是 int 类型的每个元素值
}? 根本原因分析
z 是一个数组引用变量,类型为 int[]。它本身存储的是该数组在堆内存中的地址(即对象标识),而非数组内容。
System.out.println(z) 实际调用的是 z.toString()。由于 int[] 是 JVM 内置的数组类,未重写 toString() 方法,因此默认继承自 Object 类,输出格式为:
[I@
其中 [I 表示“一维整型数组”([ 代表数组,I 是 int 的内部类型签名),@ 后为哈希码(非真实内存地址,但可视为对象唯一标识)。-
而 for (int i : z) 是增强for循环的语法糖,编译器会将其自动展开为按索引取值的等效逻辑:
立即学习“Java免费学习笔记(深入)”;
for (int idx = 0; idx < z.length; idx++) { int i = z[idx]; // ✅ 显式取出第 idx 个 int 元素 System.out.println(i); }因此 i 是基本类型 int,println(int) 会直接输出数值,无需调用 toString()。
✅ 正确写法:两种循环都应访问元素而非数组
| 循环类型 | 正确写法 | 说明 |
|---|---|---|
| 普通 for | System.out.println(z[i]); | 使用索引访问单个元素 |
| 增强 for | System.out.println(i); | 循环变量 i 已是解包后的元素值 |
修正后的完整示例:
public class ArrayReturn {
public static int[] multi(int[] a) {
for (int i = 0; i < a.length; i++) {
a[i] = a[i] * 2;
}
return a;
}
public static void main(String[] args) {
int[] ar = {2, 3, 4, 5, 6, 7};
int[] z = multi(ar);
// ✅ 方式1:普通for循环 —— 必须用索引取元素
System.out.println("=== Using traditional for ===");
for (int i = 0; i < z.length; i++) {
System.out.println(z[i]); // 输出: 4, 6, 8, 10, 12, 14
}
// ✅ 方式2:增强for循环 —— 自动迭代元素
System.out.println("=== Using for-each ===");
for (int element : z) {
System.out.println(element); // 输出: 4, 6, 8, 10, 12, 14
}
}
}⚠️ 注意事项与常见误区
- 数组不是基本类型,而是对象:即使 int[] 存储基本类型元素,数组本身仍是引用类型(java.lang.Object 的子类),因此具备对象行为(如哈希码、默认 toString)。
- toString() 不可被“绕过”:System.out.println(obj) 对任意非基本类型都会调用其 toString();若未重写,就显示 [Type@hash 格式。
- 增强for不适用于需要索引的场景:如需修改数组、比较相邻元素或记录位置,仍需传统 for + 索引。
-
泛型集合同理:对 List
使用 for (String s : list) 打印的是字符串内容(因 String 重写了 toString()),但若写成 System.out.println(list) 则输出类似 [a, b, c](因 ArrayList 重写了 toString())——这进一步印证:输出内容取决于你传入的是容器本身,还是容器中的元素。
✅ 总结
你遇到的现象并非 Java 的“奇怪行为”,而是对引用变量 vs. 元素值这一基础概念的典型混淆。记住这个黄金法则:
System.out.println(x) 输出什么,完全取决于 x 的类型和值:
- 若 x 是数组引用(如 z),则输出 [I@...;
- 若 x 是数组元素(如 z[i] 或 element),且为基本类型,则直接输出数值;
- 若 x 是对象引用,则取决于其 toString() 实现。
掌握这一点,不仅能解决当前问题,更能避免在集合遍历、调试输出等场景中重复踩坑。











