【问题标题】:Why the do arrays change when access from another variable? [duplicate]为什么从另一个变量访问时数组会改变? [复制]
【发布时间】:2018-04-10 14:57:26
【问题描述】:

我已经用多种语言(例如 python 和 js)进行了尝试,每次都得到相同的一般结果:

int[] arr = {1, 2, 3, 4, 5}; 
int[] other = arr; 
other[4] = 2;
System.out.println("other[4]: " + other[4]);
System.out.println("arr[4]: " + arr[4]);
int x = 7;
int y = x;
y = 888;
System.out.println("x: " + x);
System.out.println("y: " + y);

为什么other 在修改后会更改arr,但正如应该的那样,y 在修改后不会更改x

【问题讨论】:

  • “为什么数组会改变” 那你就错了——你只有 一个 数组。
  • 请不要标记垃圾邮件,尤其是因为不同语言的答案可能不同。由于您的示例是 Java,因此我删除了 Python 标记。
  • int[] other = arr; 不会创建第二个数组。它为您提供了第二个变量,该变量引用与第一个变量相同的数组。您对数组所做的任何更改都通过这两个变量自然可见,因为它们都指向同一个位置。
  • 你在 arr 中有一个指向数组的指针,然后你将 other 设置为指向同一个数组的指针。通过任一指针访问数组将产生相同的值。
  • 有点题外话,但恕我直言,唯一真正的答案是:去用 C 语言编程,直到你了解内存发生了什么。

标签: java arrays


【解决方案1】:

您混淆的主要原因是您误认为引用类型和值类型。看看docs

这是一个漫长的讨论,但简而言之:integers 是原始类型(也称为值类型,例如 here),因此在您的示例中,xy 在内存中有一个特定的空间。 arrays 是引用类型,所以内存中只有一个数组和两个指向它的对象。

【讨论】:

  • 一个数组对象,两个指向它的引用。
【解决方案2】:

Java 有三种类型的变量:原始类型、对象类型和空类型。需要明确一点,Java 始终是按值传递的。在另一个上分配一个原语,例如 int a = b;原始变量 b 的值分配给 A。在分配对象的情况下,它也遵循相同的规则:按值传递。但在后一种情况下,值是对对象的引用。引用变量不像 C 和 C++ 中的指针,它们只是对象的句柄,因此可以访问它们并对对象的状态进行一些更改。这就是更改数组值的原因。 Java 中的任何数组都是对象。 java.lang.Object 在每个 Java 数组中都作为超类型工作,因此它继承了 Object API 中的所有函数。

【讨论】:

    【解决方案3】:

    这是因为只复制了引用,而不是内容。要使两个数组独立,您应该为目标分配新内存,然后复制所有元素

    简而言之,arrother 指向的是同一个内存,因为您将arr 指向的内存的引用复制到了other

    下面是示意图。

    Address 0x1000 :  1
    Address 0x1004:   2
    Address 0x1008:   3
    Address 0x100C:   4
    Address 0x1010:   5
    
    Address 0x4000(arr): 0x1000
    Address 0x4008(other): 0x1000
    

    所以arrother指向的是smae地址0x1000,这个地址是你分配arr时最先分配的。

    xy 只是有它们的原始值。

    0x4020(x): 7
    0x4024(y): none
    

    变成:

    0x4020(x): 7
    0x4024(y): 7
    

    y=x; 之后。然后就变成了:

    0x4020(x): 7
    0x4024(y): 888
    

    y=888;之后

    不同之处在于,许多语言中的数组变量实际上指向了实际数据的地址。原因是:如果我们每次将一个数组分配给另一个数组时都复制所有数据,那么会损失很多性能。

    【讨论】:

    • @T.J.Crowder 谢谢,编辑了我的。
    • 为什么我被否决了?
    【解决方案4】:

    基本上,数据类型不同,因此行为也不同。

    至少在 Javascript 中,int 值是原始数据类型,而数组是对象。

    请参阅这篇文章以获得更好的解释: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0

    【讨论】:

    • 显然,标签已被修改,不再是关于 JavaScript 的问题。虽然比较 Java 和 JS 或 Python 可能会有所帮助,但这篇文章并没有像现在这样回答这个问题。
    猜你喜欢
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多