gpt4 book ai didi

java - 等式 Java 数组中的奇怪之处 : References vs. 指针

转载 作者:搜寻专家 更新时间:2023-11-01 01:10:59 28 4
gpt4 key购买 nike

在理解下面的代码中发生了什么时遇到问题。数组 cd 的行为是我所期望的。但是 ab 是怎么回事? (我也用普通的标量变量尝试过这个,在任何一种情况下都没有发生令人惊讶的事情。)

输出被复制到 RH 注释中。

import java.util.Arrays;

public class ArraysParadox {

public static void main(String[] args) {

int[] c = {1, 2, 3};
int[] d = {6, 5, 4, 3};

System.out.print("c: ");
System.out.println(Arrays.toString(c)); // c: [1, 2, 3]

System.out.print("d: ");
System.out.println(Arrays.toString(d)); // d: [6, 5, 4, 3]

System.out.println("--- swap ---");
int[] tmp = c;
c = d;
d = tmp; // <----- Magic?

System.out.print("c' (=d): ");
System.out.println(Arrays.toString(c)); // c' (=d): [6, 5, 4, 3]

System.out.print("d' (=c): ");
System.out.println(Arrays.toString(d)); // d' (=c): [1, 2, 3]

System.out.println("--- c = 0 ---");
Arrays.fill(c, 0);
System.out.print("c (=0): ");
System.out.println(Arrays.toString(c)); // c (=0): [0, 0, 0, 0]

System.out.print("d (=c): ");
System.out.println(Arrays.toString(d)); // d (=c): [1, 2, 3]

System.out.println("--- d = 1 ---");
Arrays.fill(d, 1);
System.out.print("c (=d): ");
System.out.println(Arrays.toString(c)); // c (=d): [0, 0, 0, 0]

System.out.print("d (=1): ");
System.out.println(Arrays.toString(d)); // d (=1): [1, 1, 1]

System.out.println("================");

int[] a = {1, 2, 3};
int[] b = {6, 5, 4, 3};

System.out.print("a: ");
System.out.println(Arrays.toString(a)); // a: [1, 2, 3]

System.out.print("b: ");
System.out.println(Arrays.toString(b)); // b: [6, 5, 4, 3]

a = b;
System.out.print("a (=b): ");
System.out.println(Arrays.toString(a)); // a (=b): [6, 5, 4, 3]

System.out.println("--- α = 0 ---");
Arrays.fill(a, 0);
System.out.print("a (=0): ");
System.out.println(Arrays.toString(a)); // a (=0): [0, 0, 0, 0]
System.out.print("b (=a?): ");
System.out.println(Arrays.toString(b)); // b (=a?): [0, 0, 0, 0] ???

System.out.println("--- b = 1 ---");
Arrays.fill(b, 1);
System.out.print("b (=1): ");
System.out.println(Arrays.toString(b)); // b (=1): [1, 1, 1, 1]
System.out.print("a (=b?): ");
System.out.println(Arrays.toString(a)); // a (=b?): [1, 1, 1, 1]
}
}

根据这篇文章,cd 的可交换性表示按值传递:Java is Pass-by-Value, Dammit! . (我也看了java array pass by reference does not work?,但是看不懂提问者的英文,而且方法调用模糊了例子。)

请注意,注释掉 d = tmp; 行后,cd 表现出与 a< 相同的奇怪行为b。我仍然不知道该怎么做。

谁能解释一下 ab 的行为如何用值传递来解释?

编辑:附录

事实证明,我帖子中的主要问题不是按值传递,而是别名。为了弄清楚按值传递和指针之间的区别,我将以下方法添加到我的代码中并用它来(尝试)交换 cd (由上面链接的 JavaDude 文章链接的 article 建议。

static <T> void swap (T c, T d) {
T tmp = c;
c = d;
d = tmp;
}

结果是 cd 没有改变。如果 Java(如 C)将指向 cd 的指针传递给该方法,这将是可行的,但它只是传递它们的值,而原始变量保持不变。

a = b 更改为 a = b.clone();a = Arrays.copyOf(b, b.length); 给出了我期望的行为。此代码也有效:

    int[] tmp = new int[b.length];
System.arraycopy( b, 0, tmp, 0, b.length );
a = tmp;

描述的相对时间here .

最佳答案

这里没有任何“奇怪”的事情发生:数组变量是对实际数组(在其他语言中也称为指针)的引用。当您操作数组变量时,您所做的就是操作指针。

当您将一个数组变量分配给另一个数组变量时,您会为您分配的变量所指向的数组创建一个别名,并使之前被分配的变量所指向的数组符合垃圾处理条件 Collection 。因为赋值 a = b 使 a 成为 b 的别名,所以用数据填充 b 的行为与用数据填充 a:一旦赋值完成,ab 只是同一事物的两个不同名称。

按值传递而言,您的示例中没有发生任何事情:按值传递的概念仅适用于将对象作为参数传递给您调用的方法时。在您的示例中,变量 abcd 不是方法参数,它们是局部变量.您确实通过对方法 toStringfill 的引用来传递它们(或者更准确地说,您通过值将对对象的引用传递给 toStringfill,因为在 Java 中一切都是按值传递),这就是为什么通过 fill 对数组所做的修改在方法返回时可见。

关于java - 等式 Java 数组中的奇怪之处 : References vs. 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10923949/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com