Question: Coming from C++ to Java, the obvious unanswered question is why didn't Java include operator overloading?

Isn't `Complex a, b, c; a = b + c;` much simpler than `Complex a, b, c; a = b.add(c);`?

Is there a known reason for this, valid arguments for *not* allowing operator overloading? Is the reason arbitrary, or lost to time?

Answer: 
Assuming you wanted to overwrite the previous value of the object referred to by `a`, then a member function would have to be invoked.

```
Complex a, b, c;
// ...
a = b.add(c);

```

In C++, this expression tells the compiler to create three (3) objects on the stack, perform addition, and *copy* the resultant value from the temporary object into the existing object `a`.

However, in Java, `operator=` doesn't perform value copy for reference types, and users can only create new reference types, not value types. So for a user-defined type named `Complex`, assignment means to copy a reference to an existing value.

Consider instead:

```
b.set(1, 0); // initialize to real number '1'
a = b; 
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail

```

In C++, this copies the value, so the comparison will result not-equal. In Java, `operator=` performs reference copy, so `a` and `b` are now referring to the same value. As a result, the comparison will produce 'equal', since the object will compare equal to itself.

The difference between copies and references only adds to the confusion of operator overloading. As @Sebastian mentioned, Java and C# both have to deal with value and reference equality separately -- `operator+` would likely deal with values and objects, but `operator=` is already implemented to deal with references.

In C++, you should only be dealing with one kind of comparison at a time, so it can be less confusing. For example, on `Complex`, `operator=` and `operator==` are both working on values -- copying values and comparing values respectively.
The Java designers decided that operator overloading was more trouble than it was worth. Simple as that.

In a language where every object variable is actually a reference, operator overloading gets the additional hazard of being quite illogical - to a C++ programmer at least. Compare the situation with C#'s == operator overloading and `Object.Equals` and `Object.ReferenceEquals` (or whatever it's called).