Java 真的是按值传递对象吗?

发布于 2024-12-12 09:46:12 字数 545 浏览 0 评论 0原文

可能的重复: 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");
    }
}

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

Possible Duplicate:
Is Java pass by reference?

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");
    }
}

I know that Java pass by value, but why does it pass obj by reference in previous example and change it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

凉栀 2024-12-19 09:46:13

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");
     }
}

我将分步骤解释这一点:

1-声明一个名为 f 类型为 Foo 的引用并分配它是一个带有属性 "f"Foo 类型的新对象。

Foo f = new Foo("f");

在此处输入图像描述

2- 从方法端,带有名称的 Foo 类型的引用a 已声明,并且最初分配给 null

public static void changeReference(Foo a)

在此处输入图像描述

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

changeReference(f);

在此处输入图像描述

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

Foo b = new Foo("b");

在此处输入图像描述

5- a = b 正在重新分配引用 a NOT f 到其属性为 "b" 的对象。

在此处输入图像描述


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

在此处输入图像描述

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

在此处输入图像描述

我希望您现在了解在 Java 中如何将对象作为参数传递:)

Java always passes arguments by value, NOT by reference. In your example, you are still passing obj by its value, not the reference itself. Inside your method changeName, you are assigning another (local) reference, obj, to the same object you passed it as an argument. Once you modify that reference, you are modifying the original reference, obj, which is passed as an argument.


EDIT:

Let me explain this through an example:

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");
     }
}

I will explain this in steps:

1- Declaring a reference named f of type Foo and assign it to a new object of type Foo with an attribute "f".

Foo f = new Foo("f");

Enter image description here

2- From the method side, a reference of type Foo with a name a is declared and it's initially assigned to null.

public static void changeReference(Foo a)

Enter image description here

3- As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.

changeReference(f);

Enter image description here

4- Declaring a reference named b of type Foo and assign it to a new object of type Foo with an attribute "b".

Foo b = new Foo("b");

Enter image description here

5- a = b is re-assigning the reference a NOT f to the object whose its attribute is "b".

Enter image description here


6- As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute "f".

Enter image description here

7- c.setAttribute("c"); will change the attribute of the object that reference c points to it, and it's same object that reference f points to it.

Enter image description here

I hope you understand now how passing objects as arguments works in Java :)

油饼 2024-12-19 09:46:13

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

术语“按引用传递”中的“引用”也不意味着“对对象的引用”。它的意思是“对变量的引用”——函数定义(或者更确切地说,调用框架)中可以存储值的命名“存储桶”。

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

In Java, an object handle, or the identity of an object is considered a value. Passing by value means passing this handle, not a full copy of the object.

A "reference" in the term "pass by reference" also doesn't mean "reference to an object". It means "reference to a variable" – a named "bucket" in a function definition (or, rather, a call frame) that can store a value.

Passing by reference would mean the called method could change variable values in the calling method. (For example, in the C standard library, the function scanf works this way.) This isn't possible in Java. You can always change the properties of an object – they aren't considered a part of its "value". They're completely different independent objects.

握住你手 2024-12-19 09:46:13

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

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

并通过 main 方法打印“anotherName”。

It did not change obj (your code doesn't change it anyway).
Had it been passed by reference, you could have written:

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

And have "anotherName" printed by the main method.

予囚 2024-12-19 09:46:13

您正在更改 obj属性,而不是更改 obj(参数)本身。

关键是,如果您将 obj 指向 changeName 中的其他内容,则 更改将不会反映在 main 中。

有关进一步说明,请参阅这篇文章

You're changing a property of obj, not changing obj (the parameter) itself.

The point is that if you pointed obj at something else in changeName that that change would not be reflected in main.

See this post for further clarification.

阳光的暖冬 2024-12-19 09:46:13

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

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

这意味着您可以执行以下操作:

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

并且该语句

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

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

It is passing the reference to obj as a value (a bit confusing I know :)).

So let's say it makes a copy of the pointer to obj's value and pass that.

That means that you can do things like:

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

and the statement

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

is still going to refer to the old object (the one that you did setName).

孤君无依 2024-12-19 09:46:13

Java 正在传递您要传递给函数的内容的副本。当它是原始类型时 - 它将是值的副本。当它是一个对象时 - 您正在传递参考副本。在您的代码示例中,您正在修改对象属性之一,但不是引用本身,因此名称将被更改。但是,当您想在 ChangeName 函数中将新对象分配给 obj 变量时,您将更改引用,因此外部 obj 将具有旧值。

Java is passing a copy of what you're passing to your function. When it is a primitive type - it will be the copy of a value. When it is an object - you're passing the reference copy. In you're code example you're modifying one of objects properties, but not the reference itself so the name will be changed. However when you'd like to assign new object to obj variable in changeName function, then you're changing reference, so outside obj will have an old value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文