The error I get from the compiler is "The left hand side of an assignment must be a variable". My use case is deep copying, but is not really relevant.
In C++, one can assign to *this.
The question is not how to circumvent assignment to this. It's very simple, but rather what rationale is there behind the decision not to make this a variable.
Are the reasons technical or conceptual?
My guess so far - the possibility of rebuilding an Object in a random method is error-prone (conceptual), but technically possible.
Please restrain from variations of "because java specs say so". I would like to know the reason for the decision.
In C++, one can assign to *this
Yes, but you can't do this = something in C++, which I actually believe is a closer match for what you're asking about on the Java side here.
[...] what rationale is there behind the decision not to make this a variable.
I would say clarity / readability.
this was chosen to be a reserved word, probably since it's not passed as an explicit argument to a method. Using it as an ordinary parameter and being able to reassign a new value to it, would mess up readability severely.
In fact, many people argue that you shouldn't change argument-variables at all, for this very reason.
Are the reasons technical or conceptual?
Mostly conceptual I would presume. A few technical quirks would arise though. If you could reassign a value to this, you could completely hide instance variables behind local variables for example.
My guess so far - the possibility of rebuilding an Object in a random method is error-prone (conceptual), but technically possible.
I'm not sure I understand this statement fully, but yes, error prone is probably the primary reason behind the decision to make it a keyword and not a variable.
because this is final,
this is keyword, not a variable. and you can't assign something to keyword. now for a min consider if it were a reference variable in design spec..and see the example below
and it holds implicit reference to the object calling method. and it is used for reference purpose only, now consider you assign something to this so won't it break everything ?
Example
consider the following code from String class (Note: below code contains compilation error it is just to demonstrate OP the situation)
public CharSequence subSequence(int beginIndex, int endIndex) {
//if you assign something here
this = "XYZ" ;
// you can imagine the zoombie situation here
return this.substring(beginIndex, endIndex);
}
Are the reasons technical or conceptual?
IMO, conceptual.
The this keyword is a short hand for "the reference to the object whose method you are currently executing". You can't change what that object is. It simply makes no sense in the Java execution model.
Since it makes no sense for this to change, there is no sense in making it a variable.
(Note that in C++ you are assigning to *this, not this. And in Java there is no * operator and no real equivalent to it.)
If you take the view that you could change the target object for a method in mid flight, then here are some counter questions.
What is the use of doing this? What problems would this (hypothetical) linguistic feature help you solve ... that can't be solved in a more easy-to-understand way?
How would you deal with mutexes? For instance, what would happen if you assign to this in the middle of a synchronized method ... and does the proposed semantic make sense? (The problem is that you either end up executing in synchronized method on an object that you don't have a lock on ... or you have to unlock the old this and lock the new this with the complications that that entails. And besides, how does this make sense in terms of what mutexes are designed to achieve?)
How would you make sense of something like this:
class Animal {
foo(Animal other) {
this = other;
// At this point we could be executing the overridden
// Animal version of the foo method ... on a Llama.
}
}
class Llama {
foo(Animal other) {
}
}
Sure you can ascribe a semantic to this but:
you've broken encapsulation of the subclass in a way that is hard to understand, and
you've not actually achieved anything particularly useful.
If you try seriously to answer these questions, I expect you'll come to the conclusion that it would have been a bad idea to implement this. (But if you do have satisfactory answers, I'd encourage you to write them up and post them as your own Answer to your Question!)
But in reality, I doubt that the Java designers even gave this idea more than a moment's consideration. (And rightly so, IMO)
The *this = ... form of C++ is really just a shorthand for a sequence of assignments of the the attributes of the current object. We can already do that in Java ... with a sequence of normal assignments. There is certainly no need for new syntax to support this. (How often does a class reinitialize itself from the state of another class?)
I note that you commented thus:
I wonder what the semantics of this = xy; should be. What do you think it should do? – JimmyB Nov 2 '11 at 12:18
Provided xy is of the right type, the reference of this would be set to xy, making the "original" object gc-eligible - kostja Nov 2 '11 at 12:24
That won't work.
The value of this is (effectively) passed by value to the method when the method is invoked. The callee doesn't know where the this reference came from.
Even if it did, that's only one place where the reference is held. Unless null is assigned in all places, the object cannot be eligible of garbage collection.
Ignoring the fact that this is technically impossible, I do not think that your idea would be useful OR conducive to writing readable / maintainable code. Consider this:
public class MyClass {
public void kill(MyClass other) {
this = other;
}
}
MyClass mine = new MyClass();
....
mine.kill(new MyClass());
// 'mine' is now null!
Why would you want to do that? Supposing that the method name was something innocuous rather than kill, would you expect the method to be able to zap the value of mine?
I don't. In fact, I think that this would be a misfeature: useless and dangerous.
Even without these nasty "make it unreachable" semantics, I don't actually see any good use-cases for modifying this.
this isn't even a variable. It's a keyword, as defined in the Java Language Specification:
When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (§15.12), or to the object being constructed
So, it's not possible as it's not possible to assign a value to while.
The this in Java is a part of the language, a key word, not a simple variable. It was made for accessing an object from one of its methods, not another object. Assigning another object to it would cause a mess. If you want to save another objects reference in your object, just create a new variable.
The reason is just conceptual. this was made for accessing an Object itself, for example to return it in a method. Like I said, it would cause a mess if you would assign another reference to it. Tell me a reason why altering this would make sense.
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.
Assigning to *this in C++ isn't equivalent to assigning this in Java. Assigning this is, and it isn't legal in either language.
Related
I have always thought that I have to initialize a class, before I can call it's non-static method, however, I came across a solution which had a method like this in it:
public String someStringMethod(){
return new MyClass().toString();
}
So I may be new in development, but is it a good practice? Is this a better way to call a method than the "classic" (see below) way?
public String classicStringMethod(){
MyClass cl = new MyClass();
return cl.toString();
}
Do they have any performance difference? Does the first way has a "special name"?
No significant difference
As the comments explained, both approaches are semantically the same; both ways achieve the exact same result and the choice is really just a stylistic difference.
The second approach assigns the new object to a reference variable. The first approach skips the use of a reference variable. But in both cases the class was used as a definition for instantiating an object, and then the toString method was called on that object.
Semantically, first (chained/fluent) syntax usually informs you that the created object will be used only for a single chain of operations, and discarded afterwards. Since there's no explicit reference exported, it also signals that the scope of life of the object is limited to that very statement. The second (explicit) one hints that the object is/was/will be used for additional operations, be it another method calls, setting a field to it, returning it, or even just debugging. Still, the general notion of using (or not) temporary helper variables is just a stylistic one.
Keep in mind that the variable is not the object. For example, the line Dog hershey = new Dog( "Australian Shepard" , "red", "Hershey" ); uses two chunks of memory. In one chunk is the new object, holding the state data for the breed and color and name. In the other separate chunk is the reference variable hershey holding a pointer to the memory location of the memory chunk of the Dog object. The reference variable lets us later refer to the object.
Java syntax makes this jump from reference variable to object so seamlessly that we usually think of hershey as the Dog object “Hershey”, but in fact they are separate and distinct.
As for performance, any difference would be insignificant. Indeed, the compiler or JVM may well collapse the second approach’s two lines into the first approach‘s single line. I don't know for sure, and I don't really care. Neither should you. Our job is to write clear readable code. The job of the compiler and JVM is to run that code reliably, efficiently, and fast. Attempting micro-optimizations has been shown many times to be futile (or even counter-productive) as the JVM implementations are extremely sophisticated pieces of software engineering, highly-tuned for making such optimizations. You can best assist the compilers and JVMs by writing simple straight-forward code without “cleverness”.
Note that the second approach can make debugging easier, because your debugger can inspect the instantiated object by accessing the object via the reference variable, and because you can set a line breakpoint on that particular constructor call explicitly.
I have a rather simple question with an inkling as to what the answer is.
My generalized question:
What is actually going on when you declare a member variable, be it public or private, and for all permutations of variable types, e.g. static vs const vs regular variables?
class some_class
{
private:
static const std::string str;
public:
...
}
I have kind of realized that in C++ there is no notion of a non-variable, that is, a non-constructed variable as I was kind of taught to believe exists with languages like Java. The same may also be true in Java, however it is not the way I was taught to think of things so I'm trying to come up with the correct way to think of these non-initialized variables.
public class main {
public static void main(String[] args) {
String str; // A kind of non-variable, or non-constructed variable (refers to null).
str = new String(); // Now this variable actually refers to an object rather than null, it is a constructed variable.
}
}
Since C++ allows you to initialize member variables in the constructor through initializer lists, and I have proven to myself via use of a debugger that the variable doesn't exist before it is initialized through the initializer list (either explicitly or by default), what is, then, actually going on behind the scenes when you declare the member variable?
Tricky question -- it's ambiguous depending on perspective.
From a pseudo-machine perspective, normally adding a non-static plain old data type to a class makes that class type bigger. The compiler also figures out how to align it and relative memory offsets to address it relative to the object in the resulting machine code.
This is pseudo-machine level because at the machine level, data types don't actually exist: just raw bits and bytes, registers, instructions, things like that.
When you add a non-primitive user-defined type, this recurses and the compiler generates the instructions to access the members of the member and so on.
From a higher level, adding members to a class makes the member accessible from instances (objects) of the class. The constructor initializes those members, and the destructor destroys them (recursively triggering destructors of members that have non-trivial destructors, and likewise for constructors in the construction phase).
Yet your example is a static member. For static members, they get stored in a data segment at the machine level and the compiler generates the code to access those static members from the data segment.
Some of this might be a bit confusing. C++ shares its legacy with C which is a hardware-level language, and its static compilation and linking affects its design. So while it can go pretty high-level, a lot of its constructs are still tied to how the hardware, compiler, and linker does things, whereas in Java, the language can make some more sensible choices in favor of programmer convenience without a language design that somewhat reflects all of these things.
Yes and no.
A variable of class type in Java is really a pointer. Unlike C and C++ pointers, it doesn't support pointer arithmetic (but that's not essential to being a pointer--for example, pointers in Pascal didn't support arithmetic either).
So, when you define a variable of class type in Java: String str;, it's pretty much equivalent to defining a pointer in C++: String *str;. You can then assign a new (or existing) String object to that, as you've shown.
Now, it's certainly possible to achieve roughly the same effect in C++ by explicitly using a pointer (or reference). There are differences though. If you use a pointer, you have to explicitly dereference that pointer to get the object to which it refers. If you use a reference, you must initialize the reference--and once you do so, that reference can never refer to any object other than the one with which it was initialized.
There are also some special rules for const variables in C++. In many cases, where you're just defining a symbolic name for a value:
static const int size = 1234;
...and you never use that variable in a way that requires it to have an address (e.g., taking its address), it usually won't be assigned an address at all. In other words, the compiler will know the value you've associated with that name, but when compilation is finished, the compiler will have substituted the value anywhere you've used that name, so the variable (as such) basically disappears (though if you have the compiler generate debugging information, it'll usually retain enough to know and display its name/type correctly).
C++ does have one other case where a variable is a little like a Java "zombie" object that's been declared but not initialized. If you move from an object: object x = std::move(y);, after the move is complete the source of the move (y in this case) can be in a rather strange state where it exists, but about all you can really do with it is assign a new value to it. Just for example, in the case of a string, it might be an empty string--but it also could retain exactly the value it had before the move, or it could contain some other value (e.g., the value that the destination string held before the move).
Even that, however, is a little bit different--even though you don't know its state, it's still an object that should maintain the invariants of its class--for example, if you move from a string, and then ask for the string's length, that length should match up with what the string actually contains--if (for example) you print it out, you don't know what string will print out, but you should not get an equivalent of a NullPointerException--if it's an empty string, it just won't print anything out. If it's a non-empty string, the length of the data that's printed out should match up with what its .size() indicates, and so on.
The other obviously similar C++ type would be a pointer. An uninitialized pointer does not point to an object. The pointer itself exists though--it just doesn't refer to anything. Attempting to dereference it could give some sort of error message telling you that you've attempted to use a null pointer--but unless it has static storage duration, or you've explicitly initialized it, there's no guarantee that it'll be a null pointer either--attempting to dereference it could give a garbage value, throw an exception, or almost anything else (i.e., it's undefined behavior).
I come from C/C++.
When can I speak about pointers in Java? When about references? Can I say that a variable of type Object holds a reference to some data, ie. to an instance of a class? That this variable points to a class' instance?
If Java is always copy by value, then if I pass that beforementioned variable to a function as a parameter, while the variable itself is getting copied, the content of it is still a reference to the class' instance, so that by any practical means it wasn't really a copy by value, as the instance of the class has not been copied, but the reference was, right?
What do Java developers get annoyed to listen to when speaking with C/C++ developers in this context?
It's somehow a hard to formulate question, I hope I managed to get the point across.
Update To reformulate: Can I speak feely about references and pointers using the meaning I learned while learning C/C++ and rest assured that Java developers are picking up the same meaning I'm putting into it?
Update 2 So would it be correct to asume that the word "pointer" is meaningless / should not be used in Java?
It wil be easier to grasp, if you first understand what is kept where in memory (Stack vs Heap), as you have minimal control over memory management compared to C++. Once that's out of the way, it will be easier to understand what's value and what's reference type and how pass by value and pass by reference works. Java is strictly pass by value, but not every data type is a value type. I hope that helps.
This is a good start:
http://www.journaldev.com/4098/java-heap-memory-vs-stack-memory-difference
I'm currently learning C++ and trying to get used to the standard data structures that come with it, but they all seem very bare. For example, list doesn't have simple accessors like get(index) that I'm used to in Java. Methods like pop_back and pop_front don't return the object in the list either. So you have to do something like:
Object blah = myList.back();
myList.pop_back();
Instead of something simple like:
Object blah = myList.pop_back();
In Java, just about every data structure returns the object back so you don't have to make these extra calls. Why is the STL containers for C++ designed like this? Are common operations like this that I do in Java not so common for C++?
edit: Sorry, I guess my question was worded very poorly to get all these downvotes, but surely somebody could have edited it. To clarify, I'm wondering why the STL data structures are created like this in comparison to Java. Or am I using the wrong set of data structures to begin with? My point is that these seem like common operations you might use on (in my example) a list and surely everybody does not want to write their own implementation each time.
edit: reworded the question to be more clear.
Quite a few have already answered the specific points you raised, so I'll try to take a look for a second at the larger picture.
One of the must fundamental differences between Java and C++ is that C++ works primarily with values, while Java works primarily with references.
For example, if I have something like:
class X {
// ...
};
// ...
X x;
In Java, x is only a reference to an object of type X. To have an actual object of type X for it to refer to, I normally have something like: X x = new X;. In C++, however, X x;, by itself, defines an object of type X, not just a reference to an object. We can use that object directly, not via a reference (i.e., a pointer in disguise).
Although this may initially seem like a fairly trivial difference, the effects are substantial and pervasive. One effect (probably the most important in this case) is that in Java, returning a value does not involve copying the object itself at all. It just involves copying a reference to the value. This is normally presumed to be extremely inexpensive and (probably more importantly) completely safe -- it can never throw an exception.
In C++, you're dealing directly with values instead. When you return an object, you're not just returning a reference to the existing object, you're returning that object's value, usually in the form of a copy of that object's state. Of course, it's also possible to return a reference (or pointer) if you want, but to make that happen, you have to make it explicit.
The standard containers are (if anything) even more heavily oriented toward working with values rather than references. When you add a value to a collection, what gets added is a copy of the value you passed, and when you get something back out, you get a copy of the value that was in the container itself.
Among other things, this means that while returning a value might be cheap and safe just like in Java, it can also be expensive and/or throw an exception. If the programmer wants to store pointers, s/he can certainly do so -- but the language doesn't require it like Java does. Since returning an object can be expensive and/or throw, the containers in the standard library are generally built around ensuring they can work reasonably well if copying is expensive, and (more importantly) work correctly, even when/if copying throws an exception.
This basic difference in design accounts not only for the differences you've pointed out, but quite a few more as well.
back() returns a reference to the final element of the vector, which makes it nearly free to call. pop_back() calls the destructor of the final element of the vector.
So clearly pop_back() cannot return a reference to an element that is destroyed. So for your syntax to work, pop_back() would have to return a copy of the element before it is destroyed.
Now, in the case where you do not want that copy, we just needlessly made a copy.
The goal of C++ standard containers is to give you nearly bare-metal performance wrapped up in nice, easy to use dressing. For the most part, they do NOT sacrifice performance for ease of use -- and a pop_back() that returned a copy of the last element would be sacrificing performance for ease of use.
There could be a pop-and-get-back method, but it would duplicate other functionality. And it would be less efficient in many cases than back-and-pop.
As a concrete example,
vector<foo> vec; // with some data in it
foo f = std::move( vec.back() ); // tells the compiler that the copy in vec is going away
vec.pop_back(); // removes the last element
note that the move had to be done before the element was destroyed to avoid creating an extra temporary copy... pop_back_and_get_value() would have to destroy the element before it returned, and the assignment would happen after it returned, which is wasteful.
A list doesn't have a get(index) method because accessing a linked list by index is very inefficient. The STL has a philosophy of only providing methods that can be implemented somewhat efficiently. If you want to access a list by index in spite of the inefficiency, it's easy to implement yourself.
The reason that pop_back doesn't return a copy is that the copy constructor of the return value will be called after the function returns (excluding RVO/NRVO). If this copy constructor throws an exception, you have removed the item from the list without properly returning a copy. This means that the method would not be exception-safe. By separating the two operations, the STL encourages programming in an exception-safe manner.
Why is the STL containers for C++ designed like this?
I think Bjarne Stroustrup put it best:
C++ is lean and mean. The underlying principle is that you don't pay
for what you don't use.
In the case of a pop() method that would return the item, consider that in order to both remove the item and return it, that item could not be returned by reference. The referent no longer exists because it was just pop()ed. It could be returned by pointer, but only if you make a new copy of the original, and that's wasteful. So it would most likely be returned by value which has the potential to make a deep copy. In many cases it won't make a deep copy (through copy elision), and in other cases that deep copy would be trivial. But in some cases, such as large buffers, that copy could be extremely expensive and in a few, such as resource locks, it might even be impossible.
C++ is intended to be general-purpose, and it is intended to be fast as possible. General-purpose doesn't necessarily mean "easy to use for simple use cases" but "an appropriate platform for the widest range of applications."
list doesn't even have simple accessors like get(index)
Why should it? A method that lets you access the n-th element from the list would hide the complexity of O(n) of the operation, and that's the reason C++ doesn't offer it. For the same reason, C++'s std::vector doesn't offer a pop_front() function, since that one would also be O(N) in the size of the vector.
Methods like pop_back and pop_front don't return the object in the list either.
The reason is exception safety. Also, since C++ has free functions, it's not hard to write such an extension to the operations of std::list or any standard container.
template<class Cont>
typename Cont::value_type return_pop_back(Cont& c){
typename Cont::value_type v = c.back();
c.pop_back();
return v;
}
It should be noted, though, that the above function is not exception-safe, meaning if the return v; throws, you'll have a changed container and a lost object.
Concerning pop()-like functions, there are two things (at least) to consider:
1) There is no clear and safe action for a returning pop_back() or pop_front() for cases when there is nothing there to return.
2) These functions would return by value. If there were an exception thrown in the copy constructor of the type stored in the container, the item would be removed from the container and lost. I guess this was deemed to be undesirable and unsafe.
Concerning access to list, it is a general design principle of the standard library not to avoid providing inefficient operations. std::list is a double-linked list, and accessing a list element by index means traversing the list from the beginning or end until you get to the desired position. If you want to do this, you can provide your own helper function. But if you need random access to elements, then you should probably use a structure other than a list.
In Java a pop of a general interface can return a reference to the object popped.
In C++ returning the corresponding thing is to return by value.
But in the case of non-movable non-POD objects the copy construction might throw an exception. Then, an element would have been removed and yet not have been made accessible to the client code. A convenience return-by-value popper can always be defined in terms of more basic inspector and pure popper, but not vice versa.
This is also a difference in philosophy.
With C++ the standard library only provides basic building blocks, not directly usable functionality (in general). The idea is that you're free to choose from thousands of third party libraries, but that freedom of choice comes at a great cost, in usability, portability, training, etc. In contrast, with Java you have mostly all you need (for typical Java programming) in the standard library, but you're not effectively free to choose (which is another kind of cost).
In some Java literature, The statement
The reference type of the Java virtual
machine is cleverly named
reference
is widely popular. However, authors tend not to explain more why such statement is valid. Another thing that would make me understand this more is
What does the reference type of the JVM means ? Does the JVM represent itself in the heap ?
Would appreciate a lot an explanation on this statement.
Thank you,
Ashmawy
The word you're looking for here is irony:
the use of words to convey a meaning that is the opposite of its literal meaning
The use of "clever" in that sentence is clearly ironic. "The reference type of the Java virtual machine is given the clearly really stupidly obvious name 'reference'" is another way to read that sentence.
I think the cleverly part relates to the fact that a reference type is typically called a pointer, which necessitates the reader to learn two terms. The JVM terminology simply uses the term reference for this.
There's also a historical context.
When Java was introduced, its biggest competitor was C++. C++'s main problem was that it was deemed to be too difficult. Java initially positioned itself as the easy alternative to C++. It had a syntax very close to C++, but all the difficult stuff (operator overloading, templates, multiple pass-by mechanisms) etc were removed from the language.
And now comes the catch...
Java was initially marketed as not having pointers. The rationale for saying this was that pointers were deemed the most difficult thing of C++, so if Java would not have them, it had to be a simpler language.
The clever part thus comes from simply inventing another term for 'pointer'. Call them reference and you can state Java does not have pointers (but references).
This has lead to many debates and caused a good amount of confusion, especially since C++ already had the term 'reference' and uses it for something else (though conceptually a little related). The debate usually centers around two camps where one of them claims Java indeed does not have pointers, since you can't do pointer arithmetic with them and they don't directly represent memory addresses, while the other camp states that you don't have to be able to do arithmetic with a pointer to call it a pointer.
Put differently, whether it was clever to use the term reference is still open for debate.
This becomes clearer when the whole paragraph is taken into context:
The reference type of the Java virtual machine is cleverly named reference. Values of type reference come in three flavors: the class type, the interface type, and the array type. All three types have values that are references to dynamically created objects. The class type's values are references to class instances. The array type's values are references to arrays, which are full-fledged objects in the Java virtual machine. The interface type's values are references to class instances that implement an interface. One other reference value is the null value, which indicates the reference variable doesn't refer to any object.
(Taken from http://javadeveloper-jayaprakash-m.blogspot.com/)
I would assume from this that the "cleverly named" bit is referring to the fact that the references come in three different types and the JVM can distinguish between each one.
Or maybe it is only notion to express different approach taken by JVM designers for memory management.
If you'll remember in C/C++ one have freedom to allocate memory for variable either in local stack or in global heap. It is possible in C++ to allocate memory for object in method's local stack and then pass entire object as a parameter to other methods.
Java designers took away this freedom from developers. You just cannot create objects in local stack, only in global heap. So every variable of type Class/Interface/Array is indeed a reference to some memory address in the heap. And you cannot pass object by value only by reference.
If you don't have a choice - than you don't even need to think about what type of variable you have - value type or reference type.