3
public class TestArray {
    public static void main(String[] args) {
        int[] ar = {1,2,3,4,5,6,7,8,9};

        shiftRight(ar);
        for (int i = 0; i < ar.length; i++) {
            System.out.print(ar[i]);
        }
        // prints: 912345678 -- good
        System.out.println();

        reverseArray(ar);
        for (int i = 0; i < ar.length; i++) {
            System.out.println(ar[i]);
        }
        // prints: 91234567 -- I don't understand       
        System.out.println();       
    }
    public static void shiftRight(int[] ar) {
        int temp = ar[ar.length - 1];
        for (int i = ar.length - 1; i > 0; i--) {
            ar[i] = ar[i - 1];
        }
        ar[0] = temp;
    }
    public static void reverseArray(int[] ar) {
        int[] temp = new int[ar.length];
        for (int i = 0, j = temp.length - 1; i < ar.length; i++, j--) {
            temp[i] = ar[j];
        }
        ar = temp;
        for (int i = 0; i < ar.length; i++) {
            System.out.print(ar[i]);
        }
        // prints: 876543219
        System.out.println();
    }
}

将数组传递给参数会导致将对数组的引用传递给参数;如果在方法内更改了数组参数,则该更改将在方法外可见。

第一种方法 ,shiftRight符合我的预期:它改变了方法之外的数组。

但是,第二种方法不会更改方法之外的数组。但是在方法内部运行 for 循环会打印正确的值。为什么没有ar指向的引用temp?是因为temp当方法停止时变量被破坏了——这也会杀死引用吗?即使是这种情况,为什么 Java 会采用ar指向 的引用,temp然后将其重新应用为 的原始引用ar

谢谢你。

4

4 回答 4

4

在 Java 中,说对象通过引用传递是一种用词不当。更准确的说法是对对象的引用是按值传递的。

reverseArray按值传递数组引用。local 参数是对数组的引用的副本。稍后当你说

ar = temp;

您只将本地 ar指向,而不是来自temp的原始数组引用。armain

另一方面,在shiftRight方法中,您通过复制的引用直接访问了数组,因此原始数组的内容发生了变化,方法按预期工作。

于 2013-07-11T22:35:25.603 回答
0

问题是您创建了一个局部变量temp数组,然后设置ar=temp. 您需要实际修改 的内容ar,而不是创建一个新的本地数组并将复制的ar变量指向temp

尝试这样的事情。

public static void reverseArray(int[] ar) {
    int[] temp = new int[ar.length];
    System.arraycopy( ar, 0, temp, 0, ar.length );
    for (int i = 0, j = temp.length - 1; i < ar.length; i++, j--) {
        ar[i] = temp[j];
    }

    for (int i = 0; i < ar.length; i++) {
        System.out.print(ar[i]);
    }
    // prints: 876543219
    System.out.println();
}
于 2013-07-11T22:33:03.400 回答
0

reverseMethod接收它自己对数组的引用,并且不能触及调用者的引用。

换句话说,它按值接收引用;如果它选择在保存它的局部变量中存储一个新值,那很好,但它对可能存储对旧值的引用的其他地方没有影响。

于 2013-07-11T22:35:19.667 回答
0

当您将 temp 的值分配给 ar

ar = temp;

您将方法参数的指针设置为该值,这不会以任何方式修改主方法中 ar 的引用。

如果您希望您的修改“坚持”,则从该方法返回值并将其分配给 main,如下所示:

public static void main(String[] args) {
    int[] ar = {1,2,3,4,5,6,7,8,9};

    ar = reverseArray(ar);
    System.out.println();       
}

public static int[] reverseArray(int[] ar) {
    int[] temp = new int[ar.length];
    for (int i = 0, j = temp.length - 1; i < ar.length; i++, j--) {
        temp[i] = ar[j];
    }
    ar = temp;
    for (int i = 0; i < ar.length; i++) {
        System.out.print(ar[i]);
    }
    // prints: 876543219
    System.out.println();

    return ar;  // might as well return temp
}
于 2013-07-11T22:43:40.743 回答