Java 是否通过引用传递?

发布于 07-14 09:05 字数 67 浏览 7 评论 0原文

Java 真的支持引用传递吗?

如果不是,为什么我们需要 == 运算符来查找具有相同引用的两个对象?

Does Java really support passing by reference?

If it doesn't, why do we have the == operator for finding two objects with the same reference?

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

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

发布评论

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

评论(4

等你爱我2024-07-21 09:05:32

Java 使用按值传递,而不是按引用传递...

但是,对于非基本类型,该值是引用的值。

因此 == 比较对象的引用值。

Java uses pass by value, not by reference...

But, for non primitive types the value is the value of the reference.

So == compares the values of references for Objects.

相权↑美人2024-07-21 09:05:32

区别点在于“通过引用传递**”和“传递**引用”。 有时您还会看到“call-by-...”和“pass-by-...”可互换使用。 为了简单起见,我将坚持使用“pass-by-...”。

  1. 在学术、老式、FORTRAN 相关、计算机科学术语中,引用传递意味着被调用的代码可以访问(引用)调用者传递的变量。 对被调用代码中的形式参数进行赋值实际上是对调用者的变量进行了赋值。 区别在于(除其他外)按值传递,后者为被调用的代码提供调用者已知的数据(无论是什么)的副本。

  2. 在当代 Java 相关的 OO 世界中,“拥有对象的引用”意味着能够访问对象本身。 这与“拥有指针”不同,强调(除其他外)人们不会对引用进行“指针算术”。 (事实上​​,这个意义上的“引用”不一定是实际的类似指针的内存地址。)

Java 按值传递参数(在第一种意义上),但对于对象参数,该值是一个引用(在第二种感觉)。 下面是一些依赖于差异的代码。

// called
public void munge(List<String> a0, List<String> a1) {
    List<String> foo = new List<String>(); foo.add("everybody");
    a0.set(0, "Goodbye");
    a1 = foo;
}

// caller
...
List<String> l0 = new List<String>(); l0.add("Hello");
List<String> l1 = new List<String>(); l1.add("world");
munge(l0, l1);
...

munge返回后,调用者的第一个列表l0将包含“Goodbye”。 对该列表的引用被传递给 munge,后者调用该引用对象的变异方法。 (换句话说,a0 收到了 l0 值的副本,它是对字符串的引用已修改的列表。)

但是,从调用者的第二个列表 munge 返回后,l1 仍然包含 "world",因为没有调用任何方法传递的对象引用(l1 的值,按值传递munge)。 相反,参数变量 a1 被设置为新值(本地对象引用也保存在 foo 中)。

如果 Java 使用了引用传递,那么在返回时,l1 将包含 “everybody”,因为a1 会引用变量 l1,而不是简单地初始化为其值的副本。 因此,对 a1 的赋值也将是对 l1 的赋值。

另一个问题中讨论了同样的问题,使用 ASCII-艺术来说明情况。

The point of distinction is between "pass**-by-reference" and "passing a** reference". You also sometimes see "call-by-..." and "pass-by-..." used interchangeably. For simplicity, I'll stick with "pass-by-...".

  1. In academic, old-school, FORTRAN-relevant, comp-sci terminology, pass-by-reference means that the called code has access (reference) to a variable passed by the caller. Assigning to the formal parameter in the called code actually does an assignment to the caller's variable. The distinction is versus (among others) pass-by-value, which gives the called code a copy of the data (whatever it is) known to the caller.

  2. In the contemporary Java-relevant, OO world, "having a reference" to an object means being able to get to the object itself. This is distinguished from "having a pointer" to emphasize (among other things) that one doesn't do "pointer arithmetic" on a reference. (In fact, a "reference" in this sense does not necessarily have to be an actual pointer-like memory address.)

Java passes arguments by value (in the first sense), but for object arguments, the value is a reference (in the second sense). Here's a bit of code that relies on the difference.

// called
public void munge(List<String> a0, List<String> a1) {
    List<String> foo = new List<String>(); foo.add("everybody");
    a0.set(0, "Goodbye");
    a1 = foo;
}

// caller
...
List<String> l0 = new List<String>(); l0.add("Hello");
List<String> l1 = new List<String>(); l1.add("world");
munge(l0, l1);
...

Upon return from munge, the caller's first list, l0 will contain "Goodbye". A reference to that list was passed to munge, which called a mutating method on that referred-to object. (In other words, a0 received a copy of the value of l0, which was a reference to a string list that got modified.)

However, upon return from munge, the caller's second list, l1 still contains "world" because no methods were called on the passed object reference (the value of l1, passed by value to munge). Instead, the argument variable a1 got set to a new value (the local object reference also held in foo).

IF Java had used pass-by-reference, then upon return, l1 would have contained "everybody" because a1 would have referred to the variable l1 and not simply been initialized to a copy of its value. So the assignment to a1 would have also been an assignment to l1.

This same issue was discussed in another question, with ASCII-art to illustrate the situation.

我们的影子2024-07-21 09:05:32

Java使用引用传递,而是使用值传递。 原始值参数以及指向对象的指针被复制到堆栈。

== 运算符应用于比较原始值和比较对象引用。

Java does not use pass-by-reference but rather pass-by-value. Primitive value parameters are copied to the stack, as well as pointers to objects.

The == operator should be used for comparing primitive values, and for comparing object references.

︶葆Ⅱㄣ2024-07-21 09:05:32

简短的回答是否定的。 在Java 中,只有值传递,当您使用对象(例如Object obj = new Object();)时,您正在使用对象引用。 哪个按值传递。

详情请参见:Java中的参数传递

Short answer is no. In Java there is only pass-by-value, and when you are working with objects (e.g. Object obj = new Object();), you are working with object references. Which get passed by value.

For details, see: Parameter passing in Java

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