You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java数组左旋转:为何new int[]可行而直接赋值数组引用不行?

为什么Java中数组直接赋值引用和创建新数组的行为差异这么大?

Hey Vijay,这问题其实戳中了Java里数组(以及所有引用类型)的核心特性——引用传递,而非值传递,咱们一步步拆解清楚:

核心概念:Java数组是引用类型

在Java里,当你创建一个数组int[] a = new int[5];时,a并不是直接存储数组的所有元素,而是存储了一个指向内存中实际数组对象的地址(引用)。

你给出的对比代码刚好能直观体现两种写法的差异:

static int[] rotLeft(int[] a, int d) {
    int i = 0;
    int logicBreak = d;
    // 正确:创建独立的新数组
    int[] copy = new int[a.length]; 
    // 错误:引用赋值,和原数组共享内存
    // int[] copy = a; 
    while(logicBreak < a.length){
        copy[i] = a[logicBreak];
        i++;
        logicBreak++;
    }
    logicBreak = 0;
    while(logicBreak < d){
        copy[i] = a[logicBreak];
        i++;
        logicBreak++;
    }
    return copy;
}

1. int[] copy = new int[a.length]; —— 正确的原因

这行代码做了两件事:

  • 在内存中新建了一个完全独立的数组对象,长度和a一致,但初始元素都是默认值0
  • 把这个新数组的引用地址赋值给copy变量

此时copy和a指向的是内存里两个完全分离的数组。你后续对copy的元素赋值操作,只会修改这个新数组,完全不会影响原数组a。所以你把a里的元素按左旋转逻辑拷贝到copy后,返回的就是正确的结果。

2. int[] copy = a; —— 出错的原因

这行代码并没有创建新数组,只是把a变量里存储的引用地址直接赋值给了copy。也就是说,copy和a现在指向的是内存中同一个数组对象!

哪怕你觉得自己覆盖了所有元素,也会因为共享数组而出错,咱们走一遍你的逻辑举例:
假设原数组a = [1,2,3,4,5],旋转次数d=2

  • 第一个循环:logicBreak从2开始,把a[2]=3赋值给copy[0],a[3]=4给copy[1],a[4]=5给copy[2]。但因为copy和a是同一个数组,原数组已经被改成了[3,4,5,4,5]!
  • 第二个循环:你想把原数组的前2个元素(原本是1,2)赋值给copy[3]和copy[4],但此时原数组的前两个元素已经被第一个循环修改成了3和4,最终得到的数组是[3,4,5,3,4],完全不是预期的左旋转结果[3,4,5,1,2]。

两种写法的本质差异总结

写法核心行为内存状态
int[] copy = new int[a.length];创建全新的独立数组内存中存在两个数组对象,a和copy各指向一个
int[] copy = a;引用地址赋值内存中只有一个数组对象,a和copy共享它

额外小提示

其实左旋转还可以实现原地旋转(不需要额外创建数组),不过那是进阶优化的话题。现在先把引用类型的核心概念吃透,以后写Java数组、对象相关的代码就不会踩这类坑啦~

内容的提问来源于stack exchange,提问作者Vijay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:37:34