📜  Java严格按照值传递

📅  最后修改于: 2020-03-31 13:49:19             🧑  作者: Mango

考虑以下将原始类型传递给函数的Java程序。

public class Main
{
    public static void main(String[] args)
    {
        int x = 5;
        change(x);
        System.out.println(x);
    }
    public static void change(int x)
    {
        x = 10;
    }
}

输出:

5

我们将int传递给函数“ change()”,结果该整数值的更改未反映在main方法中。与C/C++一样,Java创建在方法中传递变量的副本,然后进行操作。因此,更改不会反映在主要方法中。

对象或引用如何?

在Java中,所有原始类型(例如int,char等)都类似于C/C++,但所有非原始类型(或任何类的对象)始终是引用。因此,当我们将对象引用传递给方法时,它变得棘手。Java创建引用的副本并将其传递给方法,但它们仍指向相同的内存引用。意味着如果将其他对象设置为通过方法内部传递的引用,则调用方法中的对象及其引用将保持不受影响。

如果将对象本身更改为引用其他位置或对象,则更改不会反映在main()。如果将引用分配给其他位置,则更改不会反映在main()中。

// Java说明引用也按值传递
class Test
{
    int x;
    Test(int i) { x = i; }
    Test()      { x = 0; }
}
class Main
{
    public static void main(String[] args)
    {
        // t是一个引用
        Test t = new Test(5);
        // 引用被传入,一份引用的副本在change中被创建
        change(t);
        // 原始t.x的值被打印
        System.out.println(t.x);
    }
    public static void change(Test t)
    {
        // 我们改变引用,指向新位置
        // 现在所有对引用的改变,不会反应在main函数中
        t = new Test();
        t.x = 10;
    }
}

输出:

5

如果不将引用分配给新位置或对象,则更改将反映回来:
如果不更改引用以引用其他对象(或内存位置),则可以对成员进行更改,并且这些更改也将反映出来。

// Java展示如果不将引用分配给新位置或对象,则更改将反映回来
class Test
{
    int x;
    Test(int i) { x = i; }
    Test()      { x = 0; }
}
class Main
{
    public static void main(String[] args)
    {
        // t是引用
        Test t = new Test(5);
        // 引用被传入,一份引用的副本在change中被创建
        change(t);
        // x的新值被打印
        System.out.println(t.x);
    }
    // This change() doesn't change the reference, it only
    // changes member of object referred by reference
    public static void change(Test t)
    {
        t.x = 10;
    }
}

输出:

10

练习:预测以下Java程序的输出

//  Test.java
class Main {
   // swap()不交换i和j
   public static void swap(Integer i, Integer j)
   {
      Integer temp = new Integer(i);
      i = j;
      j = temp;
   }
   public static void main(String[] args)
   {
      Integer i = new Integer(10);
      Integer j = new Integer(20);
      swap(i, j);
      System.out.println("i = " + i + ", j = " + j);
   }
}