用Java传递参数

时间:2014-07-04 08:55:09

标签: java pass-by-value

我知道Java总是按值传递,但我不明白为什么会这样:

public static void swap(int[] arr, int i, int j)
{
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static void main(String[] args)
{
    int[] arr = {3, 4, 5, 6};
    swap(arr, 1, 3);
    // arr becomes {3, 6, 5, 4}
}

这不起作用:

public static void swap(int[] arr, int[] arr2)
{
    int[] tmp = arr;
    arr = arr2;
    arr2 = tmp;
}
public static void main(String[] args)
{
   int[] arr = {3, 4, 5, 6};
   int[] arr2 = {1, 2, 5, 6};
   swap(arr, arr2);
}

为什么?

5 个答案:

答案 0 :(得分:14)

在第二种方法中,您尝试交换引用,这些引用无效,因为引用本身是按值传递的。

第一种方法正常工作,因为它更改了数组引用的对象(可变),它不会更改引用本身。

查看this blog post,了解有关传值和传递参考之间差异的详细信息。

答案 1 :(得分:7)

您的第一个示例是传输数组中的值。

您尝试交换引用的第二个(数组是Java中的对象)。引用是本地副本(按值传递),并且对calee上下文没有影响。

(问题#56.903关于按值调用; Stackexchange应该打开PassByValue.com; - )

答案 2 :(得分:3)

如果你曾经使用过C或C ++并且知道指针是如何工作的,那么让我想到的整个场景的代码如下:

In Java, everything is passed by value. 
In case of Objects, the reference (pointer) is passed by value.

基本上是

的交换功能
public void swap(int[] a, int[] b)
{
    etc.
}

将获得指向a int []数组的指针,以及指向b int []数组的指针。 你只需交换两个指针。你无法修改那样的指针内容。

基本上C等价物是

void swap(int* a, int* b)
{
   int* temp = a;
   a = b;
   b = temp;
}

int main(void)
{
    int a[] = {5,6,7,8};
    int b[] = {1,2,3,4};
    swap(a,b);
}

即使在C中,这只会如此:

void swap(int** a, int** b)
{
   int* temp = (*a);
   (*a) = (*b);
   (*b) = temp;
}

int main(void)
{
    int a[] = {5,6,7,8};
    int b[] = {1,2,3,4};
    swap(&a, &b);
}

当然,您无法在Java中发送引用的引用。这种意义上的指针在Java中不存在。

因此,为了在另一个函数中实际修改对象,你需要一个复制引用的“Holder”对象,但是它内部对你要修改的对象的引用实际上是对象的实际引用。对象,如果那是有道理的。

因此,以下方法可行:

public class ArrayHolder
{
    public int[] array;

    public ArrayHolder(int[] array)
    {
        this.array = array;
    }
}

public void swap(ArrayHolder a, ArrayHolder b)
{
    int[] temp = a.array;
    a.array = b.array;
    b.array = temp;
}

public static void main(String[] args)
{
    ArrayHolder aaa = new ArrayHolder(new int[] {5,6,7,8});
    ArrayHolder bbb = new ArrayHolder(new int[] {1,2,3,4});
    swap(aaa,bbb);
}

答案 3 :(得分:1)

  • 第一次交换您更改了数组的数据。 (由arr引用:引用)所以它被修改

  • 第二次交换,您更改了arr,arr2,两个局部变量。因此,当您退出该方法时,两个新变量将被销毁

答案 4 :(得分:1)

  • Arr arr2 是局部变量,因此当交换方法完成时它们将被销毁。
  • 外部交换方法,不会影响局部变量的变化。