Java真的按值传递对象吗?

MBZ*_*MBZ 27 java terminology parameter-passing pass-by-reference pass-by-value

可能重复: Java是否通过引用传递?

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道Java通过值传递,但为什么它obj在前面的示例中通过引用传递并更改它?

Eng*_*uad 103

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


编辑:

让我通过一个例子解释一下:

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");
     }
}
Run Code Online (Sandbox Code Playgroud)

我将逐步解释这个:

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

Foo f = new Foo("f");
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

2-从方法方面,声明Foo具有名称的类型引用,a并将其初始分配给null.

public static void changeReference(Foo a)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

changeReference(f);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

Foo b = new Foo("b");
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

在此输入图像描述


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

在此输入图像描述

7- c.setAttribute("c");将更改引用c指向它的对象的属性,并且它是引用f指向它的同一对象.

在此输入图像描述

我希望你现在明白如何将对象作为参数传递在Java中:)

  • 非常感谢你,详细解释. (5认同)
  • 这个解释很清楚了,但我还是有点困惑。在步骤3中,“a”指向属性为*f*的对象。对我来说,“a”似乎指向“f”也指向的对象的引用。如果对象通过值传递,“a”和“f”都应该有自己的对象。然而,它们实际上共享相同的对象(即它们指向相同对象的引用)。 (3认同)
  • @Hiroki 对象不是按值传递的。它是指向按值传递的对象的指针。Java中的变量不能包含对象,它们总是包含指向对象的指针。因此,对象不能传递给方法,它总是通过值传递给方法的指向对象的指针。 (3认同)
  • 现在我得到了"将obj作为值引用"或"发送引用副本"的意思:) (2认同)

mil*_*ose 9

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

术语"通过引用传递"中的"引用"也不表示"引用对象".它表示"引用变量" - 可以存储值的函数定义(或者更确切地说是调用框架)中的命名"存储桶".

通过引用传递意味着被调用的方法可以在调用方法中更改变量值.(例如,在C标准库中,函数以scanf这种方式工作.)这在Java中是不可能的.您始终可以更改对象的属性 - 它们不被视为其"值"的一部分.它们是完全不同的独立物体.

  • 我很欣赏这个答案,因为它解释了在 Java 中,对象属性不被视为其“值”的一部分。但是在我的世界中,允许具有自己作用域的函数或方法修改其作用域之外和调用方法作用域内的变量(或对象)是“通过引用传递”,对不起 Java 人。 (2认同)