Java and C++ – Why C++ and Java Use ‘Reference’ Differently

cjavapointersreference

In C++ a reference argument to a function allows the function to make the reference refer to something else:

int replacement = 23;

void changeNumberReference(int& reference) {
    reference = replacement;
}

int main() {
    int i = 1;
    std::cout << "i=" << i << "\n"; // i = 1;
    changeNumberReference(i);
    std::cout << "i=" << i << "\n"; // i = 23;
}

Analogously, a constant reference argument to a function will throw a compile time error if we try to change the reference:

void changeNumberReference(const int& reference) {
    reference = replacement; // compile-time error: assignment of read-only reference 'reference'
}

Now, with Java, the docs say that functions arguments of non-primitive types are references. Example from the official docs:

public void moveCircle(Circle circle, int deltaX, int deltaY) {
    // code to move origin of circle to x+deltaX, y+deltaY
    circle.setX(circle.getX() + deltaX);
    circle.setY(circle.getY() + deltaY);

    // code to assign a new reference to circle
    circle = new Circle(0, 0);
}

Then circle is assigned a reference to a new Circle object with x = y
= 0. This reassignment has no permanence, however, because the reference was passed in by value and cannot change.

To me this doesn't look at all like C++ references. It doesn't resemble regular C++ references because you cannot make it refer to something else, and it doesn't resemble C++ const references because in Java, the code that would change (but really doesn't) the reference does not throw a compile-time error.

This is more similar in behavior to C++ pointers. You can use it to change the pointed objects values, but you cannot changes the pointer's value itself in a function. Also, as with C++ pointers (but not with C++ references), in Java you can pass "null" as value for such an argument.

So my question is: Why does Java use the notion of "reference"? Is it to be understood that they don't resemble C++ references? Or do they indeed really resemble C++ references and I'm missing something?

Best Answer

Why? Because, although consistent terminology is generally good for the entire profession, language designers don't always respect the language use of other language designers, particularly if those other languages are perceived as competitors.

But really, neither use of 'reference' was a very good choice. "References" in C++ are simply a language construct to introduce aliases (alternative names for exactly the same entity) explicitly. Things would have been much clearer of they had simply called the new feature "aliases" in the first place. However, at that time the big difficulty was to make everyone understand the difference between pointers (which require dereferencing) and references (which don't), so the important thing was that it was called something other than "pointer", and not so much specifically what term to use.

Java doesn't have pointers, and is proud of it, so using "pointer" as a term was no option. However, the "references" that it does have behave quite a bit as C++'s pointers do when you pass them around - the big difference is that you can't do the nastier low-level operations (casting, adding...) on them, but they result in exactly the same semantics when you pass around handles to entities that are identical vs. entities that merely happen to be equal. Unfortunately, the term "pointer" carries so many negative low-level associations that it's unlikely ever to be accepted by the Java community.

The result is that both languages use the same vague term for two rather different things, both of which might profit from a more specific name, but neither of which is likely to be replaced any time soon. Natural language, too, can be frustrating sometimes!