Java ist ein altes Experiment…

…mit Fehlern

Viele haben schon geschrieben, was bei Java schiefgelaufen ist, aber die Meisten lassen sich übermäßig über Teilaspekte wie die Syntax oder Javas Langsamkeit aus. Ich ärgere mich hauptsächlich über Inkonsistenz und danebengegangene Designentscheidungen.

Typsystem

Kommen wir zur Sache

Nichts gegen ein statisches Typsystem – wenn man’s braucht… – aber es gibt einigen vermeidbaren Stress. z. B. das Fehlen der Möglichkeit, eine Methode mehrere Werte zurückgeben zu lassen. Und die Problemlösung kommt sofort: Tupel! Man könnte argumentieren, dass man stattdessen die Rückgabewerte in eigene Klassen kapseln kann, aber dann hat man nicht bedacht, dass 1. Klassen nicht dafür da sind, einzelnen Methoden zu dienen, und man 2. mit dem selben Argument gegen mehrere Methodenparameter vorgehen kann, und Methoden mit höchstens einem Parameter wünscht sich doch wirklich niemand. Es sei denn, dieses eine Argument ist eben auch ein Tupel, wie in vielen funktionalen Sprachen zu sehen.

 count(String s) {
	return 
}

public static void main(String[] args) {
	String foo = "foo";
	String bar, int c = count(foo);
}]]>
Vielleicht sind die <> nicht die beste syntatktische Entscheidung, aber ihr versteht, was ich meine.

Ich sage nur Object[]s. Wer hat noch nicht versucht, irgendwelche Behältnisse für generische Objekte anzufertigen und diese dann wieder zurückzuholen? Ein furchtbares gecaste ist das. eine einzelne Get-Methode, die ein Object zurückliefert, das dann gecastet wird oder eine getInt, eine getString und eine getBool-Methode – alles eklig.

Operatorn & Primitives

Egal bei wie vielen Dingen ihr mir nicht zustimmt, zwei Sachen in Java sind verdammt inkonsistent:

== und .equals()

In Java gibt es Primitives und Objects. Das war eine Bescheuerte Entscheidung, weil man Primitives nur sehr eingeschränkt wie Objekte behandeln kann. (Eigentlich gar nicht, aber weil einige Amok gelaufen sind, wurde in Java ein cheat eingabaut. Das it ein häufig anzutreffendes Muster in Java’s Design.) Sie haben keine Methoden und werden mit Operatoren verändert und verglichen. Objekte nicht, die verändert und vergleicht man über Methoden. Was dämlich klingt, wird vollends absurd, weil das nicht auf die String-Klasse zutrifft. Die vergleicht man zwar mit Methoden, konkateniert sie aber mit Operatoren, obwohl sie am Besten überhaupt nicht konkateniert werden sollten, sondern per StringBuilder erstellt. Hä?

Und alles zusammen ist dermaßen blödsinnig und unintuitiv, dass ein Mensch, der Java programmieren will erst wissen muss, was Pointer, der Heap, der Stack und der ganze Low-Level-Kram ist, der angeblich in einer High-Level-Programmiersprache wie Java gar nicht für den Programmierer relevant ist. Wie wärs damit: == gibt true zurück, wenn die verglichenen Objekte Inhaltsgleich sind (x = s.clone()x==s) und is dann, wenn sie identisch sind (x = sx is s). Und das für sowohl Objekte als auch für Primitives, wenn die umbedingt jemand haben will.

Operator Overloading

OK, die String-Klasse hat es, warum der Rest nicht? Wenn, dann bitte:

 pureJava = new Array("iAmPure","meToo");
String essenceOfPurity = pureJava.get(0).cloneWithAppended(pureJava.get(1))]]>
Traurigerweise sehen Javaprogramme tatsächlich so aus, wenn man mal nicht ausschließlich mit Strings arbeitet. Aber das kommt selten vor, weil viele Javaprogrammierer es für sinnreich erachten, Methodensignaturen ausschließlich mit Stringargumenten zu befüllen.

Aber das ist eine andere Geschichte…