Assigning to (*this)
in C++ performs a copy operation -- treating the object as a value-type.
Java does not use the concept of a value-type for classes. Object assignment is always by-reference.
To copy an object as if it were a value-type: How do I copy an object in Java?
The terminology used for Java is confusing though: Is Java “pass-by-reference” or “pass-by-value”
Answer: Java passes references by value. (from here)
In other words, because Java never treats non-primitives as value-types, every class-type variable is a reference (effectively a pointer).
So when I say, "object assignment is always by-reference", it might be more technically accurate to phrase that as "object assignment is always by the value of the reference".
The practical implication of the distinction drawn by Java always being pass-by-value is embodied in the question "How do I make my swap function in java?", and its answer: You can't. Languages such as C and C++ are able to provide swap functions because they, unlike Java, allow you to assign from any variable by using a reference to that variable -- thus allowing you to change its value (if non-const) without changing the contents of the object that it previously referenced.
It could make your head spin to try to think this all the way through, but here goes nothing...
- Java class-type variables are always "references" which are effectively pointers.
- Java pointers are primitive types.
- Java assignment is always by the value of the underlying primitive (the pointer in this case).
- Java simply has no mechanism equivalent to C/C++ pass-by-reference that would allow you to indirectly modify a free-standing primitive type, which may be a "pointer" such as
this
.
Additionally, it is interesting to note that C++ actually has two different syntaxes for pass-by-reference. One is based on explicit pointers, and was inherited from the C language. The other is based on the C++ reference-type operator &
. [There is also the C++ smart pointer form of reference management, but that is more akin to Java-like semantics -- where the references themselves are passed by value.]
Note: In the above discussion assign-by and pass-by are generally interchangeable terminology. Underlying any assignment, is a conceptual operator function that performs the assignment based on the right-hand-side object being passed in.
So coming back to the original question: If you could assign to this
in Java, that would imply changing the value of the reference held by this
. That is actually equivalent to assigning directly to this
in C++, which is not legal in that language either.
In both Java and C++, this
is effectively a pointer that cannot be modified. Java seems different because it uses the .
operator to dereference the pointer -- which, if you're used to C++ syntax, gives you the impression that it isn't one.
You can, of course, write something in Java that is similar to a C++ copy constructor, but unlike with C++, there is no way of getting around the fact that the implementation will need to be supplied in terms of an explicit member-wise initialization. [In C++ you can avoid this, ultimately, only because the compiler will provide a member-wise implementation of the assignment operator for you.]
The Java limitation that you can't copy to this
as a whole is sort-of artificial though. You can achieve exactly the same result by writing it out member-wise, but the language just doesn't have a natural way of specifying such an operation to be performed on a this
-- the C++ syntax, (*this)
doesn't have an analogue in Java.
And, in fact, there is no built-in operation in Java that reassigns the contents of any existing object -- even if it's not referred to as this
. [Such an operation is probably more important for stack-based objects such as are common in C++.]
Regarding the use-case of performing a deep copy: It's complicated in Java.
For C++, a value-type-oriented language. The semantic intention of assignment is generally obvious. If I say a=b
, I typically want a
to become and independent clone of b
, containing an equal value. C++ does this automatically for assignment, and there are plans to automate the process, also, for the comparison.
For Java, and other reference-oriented languages, copying an object, in a generic sense, has ambiguous meaning. Primitives aside, Java doesn't differentiate between value-types and reference-types, so copying an object has to consider every nested class-type member (including those of the parent) and decide, on a case-by-case basis, if that member object should be copied or just referenced. If left to default implementations, there is a very good chance that result would not be what you want.
Comparing objects for equality in Java suffers from the same ambiguities.
Based on all of this, the answer to the underlying question: why can't I copy an object by some simple, automatically generated, operation on this
, is that fundamentally, Java doesn't have a clear notion of what it means to copy an object.
One last point, to answer the literal question:
What rationale is there behind the decision not to make this
a variable?
It would simply be pointless to do so. The value of this
is just a pointer that has been passed to a function, and if you were able to change the value of this
, it could not directly affect whatever object, or reference, was used to invoke that method. After all, Java is pass-by-value.
this
, it doesn't mean you should to it. Creating a new variable would do the same, without causing any mess. – Artemathis
would be set toxy
, making the "original" object gc-eligible – Prefecture