6

如果使用 调用函数Call-by-Reference,则对函数内部变量所做的任何更改都会立即影响调用者。而对于Call-by-Sharing,它在函数结束时受到影响。

问题 1: Java 使用Call-by-Sharing而不是Call-by-Reference?

问题2:我认为这Call-by-SharingCall-by-Reference 在多线程时不同。创建它只是为了减少在其他线程中使用时对值的并发覆盖;提供一致性。我对吗?

4

3 回答 3

9

我建议您不要使用“通过共享调用”的术语。正如这篇维基百科文章所述:

“但是,‘共享调用’这个术语并不常用;这个术语在不同的来源中是不一致的。例如,在 Java 社区中,他们说 Java 是按值传递的,而在 Ruby 社区中,他们说 Ruby 是按引用传递[需要引用],尽管这两种语言表现出相同的语义。共享调用意味着该语言中的值基于对象而不是原始类型。”

“尽管这个术语在 Python 社区中广泛使用,但在 Java 和 Visual Basic 等其他语言中,相同的语义通常被描述为按值调用,其中的值被暗示为对对象的引用。”

底线是 Java 使用“共享调用”......但他们不这么称呼它,如果您希望 Java 人理解您,您可能也不应该这样做。


我认为仅在多线程时,共享调用与引用调用不同。创建它只是为了减少在其他线程中使用时对值的并发覆盖;提供一致性。我对吗?

不,你不对。

在值是对象引用的情况下,“通过共享调用”实际上意味着“按值调用”。真正的“引用调用”意味着您(实际上)正在传递变量的地址,并且被调用的方法可以更新变量。

于 2012-12-17T03:12:26.297 回答
2

众所周知,Java 是按值传递的(使用更常见的白话),但是由于将对象引用传递给方法允许该方法修改调用者范围内的对象这一事实引起了很多混淆(即,他们“共享”对象)。因此,有些人错误地认为 Java 是对非原始对象的传递引用。据我了解,说某事是“共享调用”只是清楚地表明我们传递的值是对对象的引用,而不是对象本身。

相比之下,像 R 这样的语言是按值传递的,但是将像向量这样的非基元作为深拷贝传递(在我收集的技术上是写时复制),这样在方法范围内对对象所做的更改不会修改调用者范围内的向量。

要具体回答您的两个问题,是的,Java 是“共享调用”,因为我从您链接的维基百科文章中了解到它。但是,我不同意您描述的共享调用和引用调用不同。一个区别是您不能编写一种方法来通过共享调用交换两个变量。

于 2012-12-16T08:22:26.877 回答
0

在对象名称是对内存中对象的引用的语言中,当传递一个对象(对对象的引用)时,通过共享调用,引用被复制,实际参数和形式参数都将引用同一个对象. 这与按值调用或按引用调用有何不同...

所以对于极少数使用这个术语的人(即 Clu 程序员)来说,共享调用不同于按值调用,因为尽管我们确实将实参复制到了形参中,但它们都是引用;如果我们修改了形参所指的对象,程序在子程序返回后就可以通过实参看到这些变化。

Also note that during a call the value of the object can be altered, which makes it similar to call-by-reference, but it differs from call-by-reference since the reference to the object was copied so the identity of the object cannot be changed. Hence the original reference variable will still refer to the same object even after a "swap" routine that uses call-by-sharing.

于 2014-07-10T14:24:24.413 回答