在 C++ 中分配给 (*this) 执行复制操作 -- 将对象视为 值类型。
Java 没有为类使用值类型的概念。对象分配总是通过引用。
将对象复制为值类型:How do I copy an object in Java?
尽管用于 Java 的术语令人困惑:Is Java “pass-by-reference” or “pass-by-value”
答案:Java 按值传递引用。(来自here)
换句话说,因为 Java 从不将非原始类型视为值类型,所以每个类类型变量都是一个引用(实际上是一个指针)。
因此,当我说“对象分配始终是通过引用”时,将其表述为“对象分配始终由引用的值”在技术上可能更准确。 p>
Java 总是是按值传递的区别的实际含义体现在问题“How do I make my swap function in java?”中,其答案是:You can't。诸如 C 和 C++ 之类的语言能够提供交换函数,因为它们与 Java 不同,允许您通过使用对该变量的引用来从 任何变量 进行赋值,从而允许您更改其值(如果non-const) 而不更改它之前引用的对象的内容。
想一想这件事可能会让你头晕目眩,但这里什么都没有……
- Java 类类型变量始终是“引用”,实际上是指针。
- Java 指针是原始类型。
- Java 赋值始终由底层原语的值(在本例中为指针)进行。
- Java 根本没有与 C/C++ 传递引用等效的机制,它允许您间接修改独立的原始类型,它可能是“指针”,例如
this。
此外,有趣的是,C++ 实际上有两种不同的语法用于传递引用。一种是基于显式指针,并继承自 C 语言。另一个基于 C++ reference-type operator &。 [还有 C++ 智能指针 形式的引用管理,但这更类似于类似 Java 的语义——引用本身是按值传递的。]
注意:在上述讨论中,assign-by 和 pass-by 通常是可互换的术语。在任何赋值的基础上,是一个概念性的操作符函数,它根据被传入的右侧对象执行赋值。
所以回到原来的问题:如果您可以在 Java 中分配给 this,这将意味着更改 this 持有的引用的值。这实际上相当于在 C++ 中直接分配给 this,这在该语言中也是不合法的。
在 Java 和 C++ 中,this 实际上是一个无法修改的指针。 Java 似乎有所不同,因为它使用. 运算符来取消引用指针——如果您习惯于 C++ 语法,那么会给您的印象是它不是一个。
当然,您可以用 Java 编写类似于 C++ copy constructor 的东西,但与 C++ 不同的是,没有办法绕过实现需要以显式成员初始化的形式提供。 [在 C++ 中,您最终可以避免这种情况,只是因为编译器会为您提供 赋值运算符的成员实现。]
您不能将 Java 限制整体复制到 this 是有点人为的。您可以通过逐个成员编写它来获得完全相同的结果,但是该语言没有一种自然的方式来指定要在 this 上执行的此类操作 - C++语法,(*this) 在 Java 中没有类似物。
事实上,Java 中没有内置操作可以重新分配任何现有对象的内容——即使它不被称为this。 [这样的操作可能更重要对于基于堆栈的对象,例如在 C++ 中很常见。]
关于执行深拷贝的用例:It's complicated in Java.
对于 C++,一种面向值类型的语言。赋值的语义意图通常是显而易见的。如果我说a=b,我通常希望a 独立于clone 和b,包含相等的值。 C++ 会自动执行此操作以进行分配,并且有 plans 可以自动执行此过程,也可以进行比较。
对于 Java 和其他面向引用的语言,复制一个对象,在一般意义上,具有模棱两可的含义。除了原语,Java 不区分值类型和引用类型,因此复制对象必须考虑每个嵌套的类类型成员(包括父类的成员)并根据情况决定- 逐案,如果该成员对象应该被复制或只是引用。 如果留给默认实现,那么结果很可能不是您想要的。
比较 Java 中的对象是否相等受到same ambiguities 的影响。
基于所有这些,基本问题的答案:为什么我不能通过this上的一些简单、自动生成的操作来复制对象 ,是从根本上说,Java 对复制对象的含义没有一个清晰的概念。
最后一点,回答字面问题:
决定不将this 设为变量的原因是什么?
这样做毫无意义。 this 的值只是一个传递给函数的指针,如果您能够更改 this 的值,它不会直接影响用于调用该方法的任何对象或引用。毕竟,Java 是按值传递的。