I like Java but I can’t understand why it still doesn’t have operator overloading.
Everyday operator overloading
Every Java object has two (and more) methods:
String toString(): Returns a string representation of the object.boolean equals(Object obj): Indicates whether some other object is “equal to” this one.
So basically if you want to check whether Object a equals Object b, you type a.equals(b). But wait a second, there’s an operator == which checks if two integers are equal, so why not Objects? Well, because Java doesn’t know operator overloading.
And you can say whatever you want, but typing a == b is way more intuitive than typing a.equals(b).
Similar with toString(). Why not just cast this Object to a String object? (String)a is at least a little bit nicer to read than a.toString().
Any official statement?
I left out operator overloading as a fairly personal choice because I had seen too many people abuse it in C++.
James Gosling. (source)
So it people abuse a programming language feature you should not implement it? This is nonsense.
It’s like saying exceptions are evil because someone could abuse them as a return value.
Yeah. Someone could, someone will, but everyone who cares won’t use his code.
Java has operator overloading!
Yes, Java uses operator overloading. But unfortunately it can’t be influenced by the user.
Let’s see an example:
int a = 5, b = 10; int c = a + b; // c = 15 String s = "foo", p = "bar"; String o = s + p; // o = "foobar"
So Java declares two completely different meanings to the + operator. It can’t be that evil if the Java Standard does it.
Style comparison
Let’s compare some code to see what looks better.
// Java SomeComplexType a,b; if(a.equals(b)) foo(); Data d1,d2; if(d1 < d2) bar(); Vector<String> v = /* ... create and fill ... */ String s = v.elementAt(42);
compared to
// C++ SomeComplexType a,b; if(a == b) foo(); Date d1,d2; // Class overloading comparison operators if(d1 < d2) bar(); vector<string> v; /* fill */ string s = v[42];
Clearly if you re
There’s more than mumerical types
Whenever people argument about liking operator overloading others will counter with “yeah, but it’s only useful for numerical types”. Wrong.
Here are some examples:
- Every comparable class: overloading == (and !=)
- libpqxx (Postgres C++ library): [] to access rows/columns in a SELECT result.
- glibmm: various overloadings for glib::ustring. (e.g. glib::ustring s = “foo”)
- Various boost libraries for various reasons.
- many many more
So why is operator overloading important? Well, it uses the programmers knowledge about operators and appends them to other objects. Therefore if the programmer knows that comparing two integers can be accomplished by typing a == b it should also be able to be used to compare any other object.
Operator-Überladung ist immer böse, weil es verschleiert, was hinter dem Code steckt. Eins der größten Probleme von C++ ist, dass man ein Stück Code ohne Kontext nicht verstehen _kann_, weil durch z.B. Operator-Überladung der identische Code einmal dies oder einmal etwas ganz anderes bedeuten kann. (C++ ist kontext-abhhängig.)
Ich durfte mal an einem Framework (C++) mitarbeiten, bei dem der Hauptentwickler ein Verfechter von Templates und Operator-Überladung war. Glaub mir, das macht keinen Spaß. Selbst in einfachen Fällen wie in deinem []-Beispiel ist der resultierende Code verwirrend. Man _muss_ wissen, dass die verwendete Klasse den []-Operator überlädt _und_ was die Klasse in dem Fall tut. Das ist bei [] ja nun nicht immer so klar. (Was macht der Operator z.B. bei einer Map? Oder bei einem Set?) Man braucht also Kontext und Dokumentation. Das ist schlecht.
Dein Beispiel mit den Integer-Objekten ist eher weniger gut. Der ==-Operator ist klar definiert: Er vergleicht Objekt-Referenzen bzw. bei primitiven Datentypen den Wert.
Nur weil es Klassen gibt, die primitive Datentypen wrappen können, heißt das ja nicht, dass der ==-Operator in diesem speziellen Fall eine andere Funktion haben sollte. Wenn man Objekt-Referenzen vergleicht, dann ==, wenn man Objekt-Inhalte vergleicht, dann equals().
Man kann jetzt natürlich trefflich darüber streiten, ob es bei der Spezifikation von Java nicht sinnvoller gewesen wäre, primitive Datentypen gleich als Objekte zu verstehen. Nun ist es aber nicht so, und daher sind auch die Operatoren entsprechend anzuwenden.
Und selbst wenn man den ==-Operator für z.B. Integer jetzt ändern würde (wenn man könnte): Wie vergleicht man dann Referenzen? Es kommt ja durchaus mal vor, dass man auch Integer-Referenzen vergleichen möchte. Dafür brauchte man dann plötzlich noch einen Operator, oder gar eine spezielle Methode. Das klingt für mich nicht so sinnvoll, um ehrlich zu sein. Einheitlichkeit ist bei Programmiersprachen wichtig.
Mit Operator Überladung ist es wie mit Klassenvererbung, Methoden-Namensgebung, usw. Man muss das ganze sinnvoll einsetzen.
[] bei einem Set zu überladen macht keinen Sinn, bei einer Map hingegen sehr wohl.
Eine Map ist ja eine eine eindeutige Beziehung A->B (wobei jedes A nur einem B zugeordnet ist). Folglich macht map[A] natürlich Sinn und es spricht auch nichts dagegen es einzusetzen.
Folglich gilt natürlich: Überlade Operatoren dann, wenn es sinnvoll ist und es dem Entwickler ohne groß nachzuschauen klar ist, was passiert. In den meisten Fällen, die ich bei guten libraries gesehen habe, ist dies der Fall.
Interessanter Punkt mit den Referenzen-Vergleich. Daran hatte ich wirklich nicht gedacht.
C++ umgeht halt das Problem, indem man klar den Unterschied zwischen Objekt und Pointer hat. In Java besteht da eine gewisse Transparenz.
An manchen Tagen möcht ich Leuten die gegen Operatorüberladung sind einfach ins Gesicht schlagen. Heute ist soeiner.
Graphikprogrammierung wird zu einer richtig hässlichen Sache wenn man Matrix und Vektoroperatoren nicht definieren kann aber noch schlimmer ist, dass wir im Unternehmen gerade das float primitive durch BigDecimal sollen. Wir sind echt am Überlegen auf die Genauigkeit zu pfeifen obwohl sie eigentlich erforderlich ist damit wir uns nicht mit .mul(), .add() usw. rumschlagen müssen.
===
Operator-Überladung ist immer böse, weil es verschleiert, was hinter dem Code steckt.
===
Das macht jeder Methodenaufruf. Nur weil es Leute gibt die mit dem + operator Objekte multiplizieren ist das noch lang kein Grund operatorüberladung wegzulassen. In jedem Methodenaufruf kann genausoviel blödsinn gemacht werden. Operatoren sind nichts anderes als Methoden.
I’ve been a developer for nearly 40 years, mostly in the engineering and scientific realm. Of course COBOL was useless for these types of applications so we did a lot in Assembly language. When WATFOR finally came out we could use Fortran for our needs. And finally C++ became the language of choice. I had high hopes for Java, but they were soon dashed after I saw many Java forum posts being shot down by the MVPs and experts at Sun. All we wanted was operator overloading for complex numbers, matrices, quaternions, and vectors. It’s a simple request. No changes to the runtime or JRE are needed. But over and over again the requests from the engineering and scientific community were decried.
The powers-that-be gave pitiful excuses such as “That’s just syntactic sugar.” Well then tell me what isn’t? Do you toggle your programs into the box in binary? Everything beyond that IS syntactic sugar. It’s not a would-be-nice-if request, it’s very basic and essential – a huge missing capability in Java.
Others claimed that somebody could overload the addition operator so that it performs division! Hmm. Well heck, I could overload println() so that it deletes all of the files in user-land; and that’s without operator overloading. We’re not asking to be able to overload the scoping operator – just math, indexing, and assignment. It’s just syntax – but important syntax. If you are a business/website developer you may not appreciate the criticality, but imagine that somebody takes away java.net/java.web and makes you use JNI to access sockets! I’ve written many apps with thousands of lines of matrix math.
(I guess if you’re a business-app developer, the engineering and scientific world looks scary and strange – something to actively avoid.)
So most of us left for greener pastures – often to Microsoft C# where we could do math beyond simple arithmetic without writing illegible code. After a few years away from Java I have now revisited these forums only to discover that nobody is asking for operator overloading anymore – at least not in the past few years. Why not? It’s not lack of interest. The rest of us were just smart enough to abandon ship when it made sense. So I did some research. Try to search for engineering and scientific libraries and apps in Java, then do the same for .NET. There are some Java academic projects, but not many serious products out there. The few that exist are typically rudimentary or make use of underlying C/C++ code via JNI. It seems as if almost nobody is using Java for anything but business apps, most typically websites. Graphical games, likewise – switch to .NET if you want 3D graphics, finite element analysis, solid modeling, or constructive solid geometry. Oracle/Sun is deliberately shutting out a quarter of their potential market – and it’s an important segment.
Note that this is not intended to be an insult but, rather, as advice. General Patton was once advised that there was scuttlebutt about him going around. He responded, “Thanks, but I don’t worry when I hear scuttlebutt – I worry when I stop hearing it.” Well Oracle/Sun – after looking at your forums it seems that you have stopped hearing the scuttlebutt. So my only question for you remains: “Is Java trying to be the COBOL of the 21st century?”