在古怪等同于Java中的数组:参考文献与指针 [英] Weirdness in Equated Java Arrays: References vs. Pointers

查看:194
本文介绍了在古怪等同于Java中的数组:参考文献与指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

能明白这是怎么回事N个低于code的一个问题。阵列 C 行为和 D 是我所期望的那样。但是,这是怎么回事与 A B ? (我也试图与正常的标量变量,并没有什么奇怪发生在两种情况下)。

Having a problem understanding what's going on n the code below. The behavior of arrays c and d is what I would expect. But what's going on with a and b? (I also tried this with normal, scalar variables, and nothing surprising happens in either case.)

的输出被复制到RH注释

The output is copied to the RH comments.

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]
    }
}

的ç的swapability和 D 表示,根据这个帖子传递按值: Java是传递按值,该死!。 (我也看了一下 Java数组通过引用传递不起作用?,但我无法理解提问者的英语,方法调用掩盖的例子。)

The swapability of c and d indicates pass-by-value according to this post: Java is Pass-by-Value, Dammit!. (I also looked at java array pass by reference does not work?, but I can't understand the asker's English, and the method call obscures the example.)

请注意,与行 D = tmp目录; 注释掉, C D 表现出同样的古怪行为为 A b 。不过我不知道这是怎么回事。

Notice that with the line d = tmp; commented out, c and d exhibit the same odd behavior as a and b. Still I don't know what to make of it.

谁能解释如何 A 和的 B 行为可以用通解释-by价值?

Can anyone explain how a and b's behavior can be explained with pass-by-value?

原来,帖子中的主要问题是无法通过按值,而走样。要明确传递由值和指针之间的区别,我添加了下面的方法来我的code并用它(试图)交换 C D (由文章建议通过JavaDude的文章上面链接)链接。

It turns out the main issue in my post is not pass-by-value, but aliasing. To be clear about the distinction between pass-by-value and pointers, I added the following method to my code and used it to (try to) swap c and d (suggested by an article linked by JavaDude's article linked above).

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

结果是 C D 回来不变。如果用Java代码(如C)沿指针传递这会工作到 C D 来的方法,而是它简单地传递他们的价值观,离开原来的变量保持不变。

The result is that c and d come back unchanged. This would have worked if Java (like C) passed along pointers to c and d to the method, but instead it simply passes their values, leaving the original variables unchanged.

修改 A = B A = b.clone(); A = Arrays.copyOf(b,b.length个); 给我所期待的行为。这code也可以工作:

Changing a = b to a = b.clone(); or to a = Arrays.copyOf(b, b.length); gives the behavior I was expecting. This code also works:

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

相对定时descried rel=\"nofollow\">。

Relative timing descried here.

推荐答案

有什么怪异会在这里:数组变量的引用的实际阵列(也被称为在其他语言指针)。当你操纵数组变量,你要做的就是操纵指针。

There is nothing "weird" going on here: array variables are references to the actual arrays (also known as pointers in other languages). When you manipulate array variables, all you do is manipulating pointers.

当您分配一个数组变量到另外一个,你创建的别名的到阵列由您指定的变量指向,使阵列previously指向的变量被分配符合垃圾收集。由于分配 A = B ,使 A 的别名b ,填写 b 使用数据的行为完全一样填充 A 数据:一旦分配完成, A b 仅仅是两个不同的同一件事的名字。

When you assign an array variable to another one, you create an alias to the array pointed to by the variable you assign, and make the array previously pointed to by the variable being assigned eligible for garbage collection. Because the assignment a = b makes a an alias of b, filling b with data acts exactly the same as filling a with data: once the assignment is complete, a and b are merely two different names for the same thing.

据的按值传递的来讲,没有它在你的例子是怎么回事:当你传递对象作为参数,你调用的方法按值传递的概念只适用。在你的例子,变量 A B C ,和 D 不是方法的参数,它们是局部变量。你做参考方法的toString 填写(或更多precisely,您通过值传递它们到的toString你对象的引用填写,因为在Java一切都是按值传递的),这就是为什么修改您的阵列由填写完成后,是从方法的返回可见。

As far as pass by value is concerned, none of it is going on in your example: the concept of passing by value applies only when you pass objects as parameters to the methods that you call. In your example, variables a, b, c, and d are not method parameters, they are local variables. You do pass them by reference to methods toString and fill (or more precisely, you pass by value the references to your objects to toString and fill, because in Java everything is passed by value), that is why modifications to your arrays done by fill are visible upon the return from the method.

这篇关于在古怪等同于Java中的数组:参考文献与指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆