Java真的按值传递对象吗?

Is Java really passing objects by value?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Is Java pass by reference?

1
2
3
4
5
6
7
8
9
10
public class myClass{
    public static void main(String[] args){
        myObject obj = new myObject("myName");
        changeName(obj);
        System.out.print(obj.getName()); // This prints"anotherName"
    }
    public static void changeName(myObject obj){
        obj.setName("anotherName");
    }
}

我知道Java按值传递,但是为什么它在前面的例子中引用了EDCOX1×0?


Java总是通过值传递参数,而不是通过引用传递。在您的示例中,您仍然通过其值传递obj,而不是引用本身。在方法changeName中,您将另一个(本地)引用obj分配给作为参数传递的同一对象。修改该引用后,您将修改作为参数传递的原始引用obj

编辑:

让我通过一个例子来解释这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Main
{
     public static void main(String[] args)
     {
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will change the object that the reference refers to!
     }
     public static void changeReference(Foo a)
     {
          Foo b = new Foo("b");
          a = b;
     }
     public static void modifyReference(Foo c)
     {
          c.setAttribute("c");
     }
}

我将分步骤解释:

1-声明一个名为Foo类型的f的引用,并将其分配给具有"f"属性的Foo类型的新对象。

1
Foo f = new Foo("f");

Enter image description here

2-从方法方面,声明了一个名为aFoo类型的引用,它最初分配给null

1
public static void changeReference(Foo a)

Enter image description here

3-当您调用方法changeReference时,引用a将分配给作为参数传递的对象。

1
changeReference(f);

Enter image description here

4-声明一个名为Foo类型的b的引用,并将其分配给具有"b"属性的Foo类型的新对象。

1
Foo b = new Foo("b");

Enter image description here

5-a = b将引用a而不是f重新分配给其属性为"b"的对象。

Enter image description here

6-当您调用modifyReference(Foo c)方法时,将创建一个引用c并将其分配给具有属性"f"的对象。

Enter image description here

7-c.setAttribute("c");将更改引用c指向它的对象的属性,它与引用f指向它的对象相同。

Enter image description here

我希望您现在理解如何将对象作为参数在Java中工作:


在Java中,对象句柄或对象的标识被认为是一个值。传递值意味着传递此句柄,而不是对象的完整副本。

术语"传递引用"中的"引用"也不表示"对对象的引用"。它的意思是"对变量的引用"—函数定义(或者更确切地说,调用帧)中可以存储值的命名"bucket"。

通过引用传递意味着被调用的方法可以更改调用方法中的变量值。(例如,在C标准库中,函数EDOCX1 OR 32是这样工作的)这在Java中是不可能的。你总是可以改变一个对象的属性——它们不被认为是它"值"的一部分。它们是完全不同的独立物体。


它没有改变obj(你的代码也不会改变它)。如果它是通过引用传递的,您可能会写:

1
2
3
public static void changeName(myObject obj){
    obj = new myObject("anotherName");
}

并按主方法打印"另一个名字"。


您正在更改EDOCX1的属性〔0〕,而不是更改obj(参数)本身。

重点是,如果你把obj指向changeName中的其他东西,那么这个变化不会反映在main中。

详情请参阅本帖。


Java传递的是你传递给你的函数的副本。当它是基元类型时-它将是值的副本。当它是一个对象时-您正在传递引用副本。在代码示例中,您修改的是一个对象属性,而不是引用本身,因此名称将被更改。但是,如果您想在changename函数中将新对象赋给obj变量,那么您将更改引用,这样,在obj外部将有一个旧值。


它将对obj的引用作为一个值传递(我知道有点困惑)。

假设它复制了一个指向obj值的指针,并传递它。

这意味着你可以做如下的事情:

1
2
3
4
  public static void changeName(myObject obj){    
        obj.setName("anotherName");
        obj = new myObject();
    }

还有声明

1
System.out.print(obj.getName());

仍将引用旧对象(执行setname的对象)。