Equated Java Arrays中的奇怪之处:引用与指针

Joh*_*hnK 4 java arrays pointers

有一个问题,了解下面的代码正在发生什么.阵列的行为c,并d为我所期望的那样.但是,这是怎么回事与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]
    }
}
Run Code Online (Sandbox Code Playgroud)

根据这篇文章,可交换性cd表示传值:Java是按值传递,该死!.(我也看了一下java数组通过引用传递不起作用?但是我无法理解提问者的英文,而方法调用模糊了这个例子.)

请注意,与线d = tmp;注释,cd表现出相同的奇数行为ab.我仍然不知道该怎么做.

任何人都可以解释如何ab的行为可以通过按值来解释?

编辑:附录

事实证明我的帖子中的主要问题不是传值,而是别名.要明确有关传递的价值和指针之间的区别,我添加了下面的方法来我的代码,并用它(试图)交换c,并d(通过建议文章通过JavaDude的文章上面链接的链接).

static <T> void swap (T c, T d) {
    T tmp = c;
    c = d;
    d = tmp;
}
Run Code Online (Sandbox Code Playgroud)

结果是,cd恢复原状.如果用Java代码(如C)以及指针经过这会工作c,并d到方法,而是它只是简单地传递自己的价值观,离开原来的变量保持不变.

更改a = ba = b.clone();a = Arrays.copyOf(b, b.length);给予我期待的行为.此代码也有效:

    int[] tmp = new int[b.length];
    System.arraycopy( b, 0, tmp, 0, b.length );
    a = tmp;
Run Code Online (Sandbox Code Playgroud)

相对时间在这里描述.

das*_*ght 11

这里没有什么"怪异":数组变量是实际数组的引用(在其他语言中也称为指针).当您操作数组变量时,您所做的只是操作指针.

当您将一个数组变量到另一个,创建一个别名为指向的数组分配变量,使阵列先前指向由变量被分配进行垃圾回收.由于分配a = b,使a一个别名b,填充b数据的行为完全一样的填充a数据:一旦分配完成,ab仅仅是同一事物的两个不同的名字.

传递值而言,在您的示例中没有任何内容:仅当您将对象作为参数传递给您调用的方法时,传递值的概念才适用.在你的例子,变量a,b,c,和d是不是方法的参数,它们是局部变量.你做参考方法,通过他们toStringfill(或者更准确地说,按值引用传递给你的对象toStringfill,因为在Java一切都是按值传递),这就是为什么修改您的阵列将完成fill须待返回可见从方法.

  • 要清楚,Java完全是按值传递的,但是您总是按值传递_references_,而不是对象本身.(这与传递引用不同.) (2认同)