Kotlin 1.0 ausprobiert – eine Alternative zu Java?

Keine Zeit? Hier die Kurzversion in 30 Sekunden.
- Kotlin 1.0 ist seit dem 15. Februar 2016 draußen, JetBrains verspricht ab jetzt Abwärtskompatibilität.
- Null-Safety im Typsystem, data classes, Extension Functions und Lambdas nehmen Java viel Zeremonie ab.
- Die Interoperabilität mit Java ist sehr gut, die Unterstützung in IntelliJ ebenfalls; Java-6-Bytecode macht Kotlin für Android interessant.
- Dagegen stehen Lernkurve, ein kleineres Ökosystem, Fragen zur Langfristigkeit und spürbar längere Compile-Zeiten.
- Für ein neues, abgegrenztes Modul kann sich ein Versuch lohnen, ein Umstieg im Großen eher noch nicht.
Am 15. Februar hat JetBrains Kotlin 1.0 veröffentlicht. Die Sprache gibt es schon deutlich länger, aber erst mit der 1.0 gibt es ein Versprechen, dass Code, der heute läuft, auch mit späteren Versionen weiterläuft. Für mich war das der Anlass, es endlich selbst auszuprobieren, und zwar nicht mit einem Hallo-Welt-Programm, sondern an ein paar kleinen Hilfsklassen, die ich sonst in Java schreibe. Dieser Text ist kein Test mit Messwerten, sondern ein Erfahrungsbericht mit anschließender Abwägung.
Was sich beim Schreiben anders anfühlt
Der erste Eindruck ist: weniger Rauschen. Eine einfache Wertklasse in Java besteht aus Feldern, Konstruktor, Gettern, equals, hashCode und toString. In Kotlin reicht eine Zeile:
data class Kunde(val name: String, val alter: Int)Dazu bekommt man equals, hashCode, toString und eine copy-Methode geschenkt. Ob das ein großer Gewinn ist, hängt davon ab, wie viele solcher Klassen man hat. Bei mir sind es viele, und die IDE-Generierung in Java ist zwar bequem, aber der Code bleibt trotzdem da und will gelesen werden.
Der Punkt, der mich am meisten überzeugt hat, ist der Umgang mit null. In Kotlin unterscheidet das Typsystem zwischen String und String?. Das erste darf nie null sein, das zweite schon, und der Compiler zwingt einen, damit umzugehen:
fun laenge(text: String?): Int {
return text?.length ?: 0
}Der Operator ?. ruft die Methode nur auf, wenn der Wert nicht null ist, und ?: liefert einen Ersatzwert. In Java sieht dasselbe so aus:
static int laenge(String text) {
return text != null ? text.length() : 0;
}Das ist nicht viel länger. Der Unterschied liegt woanders: In Java sieht man dem Parameter nicht an, ob null erlaubt ist, in Kotlin steht es im Typ. Ich habe in Java-Projekten genug NullPointerExceptions gesehen, um das für einen echten Fortschritt zu halten, und nicht nur für Kosmetik.
Extension Functions erlauben es, vorhandene Klassen um Methoden zu erweitern, ohne sie anzufassen:
fun String.istLeer(): Boolean = this.trim().isEmpty()Lambdas sind ebenfalls angenehm. Java 8 hat sie nachgereicht, aber in Kotlin fühlen sie sich selbstverständlicher an, zum Beispiel kunden.filter { it.alter >= 18 }. Wer unter Java 6 oder 7 festsitzt, wird den Unterschied noch deutlicher spüren.
Java-Interop und Werkzeuge
Der Teil, der mich am wenigsten überrascht hat und trotzdem am wichtigsten ist: Kotlin lässt sich mit Java mischen, ohne dass man Brücken bauen muss. Kotlin-Code ruft Java-Klassen auf, Java-Code ruft Kotlin-Klassen auf, beides im selben Projekt. Man kann also eine einzelne Klasse umstellen und den Rest lassen, wie er ist. Das senkt die Einstiegshürde enorm, weil man keine Entscheidung für alles auf einmal treffen muss.
Die Unterstützung in IntelliJ IDEA ist erwartungsgemäß gut, schließlich kommen Sprache und Entwicklungsumgebung vom selben Hersteller. Es gibt auch ein Werkzeug, das Java-Dateien in Kotlin umwandelt. Das Ergebnis ist lesbar, aber selten so, wie man es von Hand schreiben würde; als Lernhilfe taugt es trotzdem. Für Eclipse gibt es ein Plugin, das sich in meinem Eindruck noch deutlich weniger ausgereift anfühlt.
Interessant ist, dass der Compiler Bytecode erzeugt, der mit Java 6 kompatibel ist. Das ist vor allem für Android relevant, wo man bei der Sprachversion bisher ziemlich eingeschränkt ist. Dort Lambdas und Null-Safety zu bekommen, ohne auf eine neue Laufzeit zu warten, ist ein starkes Argument. Ich selbst arbeite überwiegend an anderen Plattformen, kann das also nur aus der Beobachtung beurteilen.
Was dagegen spricht
Jetzt zur Gegenseite, denn eine neue Sprache ist keine kostenlose Verbesserung.
Lernkurve im Team. Kotlin ist nicht schwer, aber es ist eine weitere Sprache, die jemand lesen und warten können muss. Wenn nur eine Person im Projekt Kotlin versteht, ist das ein Risiko, kein Gewinn. Die Konzepte wie val und var, Smart Casts und Nullable Types sind schnell gelernt; die Idiome, mit denen man wirklich guten Kotlin-Code schreibt, dauern länger.
Build-Zeiten. Der Compiler fühlt sich spürbar langsamer an als javac. Ich habe nichts gemessen, es ist ein Eindruck, aber bei größeren Projekten und gemischtem Code wird er relevant. Ob sich das noch bessert, kann ich nicht sagen.
Ökosystem und Langfristigkeit. Eine 1.0 ist ein Anfang. Es gibt wenig Erfahrung mit großen, langlebigen Projekten, wenige Bücher, kaum Antworten auf spezielle Fragen. Außerdem hängt die Sprache stark an einem einzigen Hersteller. JetBrains hat ein offensichtliches Interesse an Kotlin, aber ob die Sprache in zehn Jahren noch gepflegt wird, weiß heute niemand. Wer Systeme baut, die lange laufen sollen, muss das einrechnen. Zum Vergleich: Scala und Groovy sind ältere Alternativen auf der JVM und haben ihre Nischen gefunden, aber keine hat Java abgelöst.
Werkzeuge außerhalb von IntelliJ. Wer ein anderes Umfeld nutzt, muss mit schlechterer Unterstützung rechnen. Auch Analyse-Werkzeuge, Code-Qualitätsprüfungen und manche Frameworks kennen Kotlin noch nicht richtig.
Wann ich es einsetzen würde
Einen Umstieg auf breiter Front würde ich im Moment nicht empfehlen. Der Gewinn an Kürze und Sicherheit ist real, aber er rechtfertigt keine Migration bestehender, funktionierender Systeme. Dort überwiegt das Risiko.
Dagegen finde ich Kotlin für ein neues, klar begrenztes Modul interessant: ein Werkzeug, ein Konverter, ein interner Dienst, etwas, das sich im Notfall überschaubar zurück nach Java übersetzen ließe. Wegen der guten Interoperabilität kann man das probieren, ohne das Gesamtprojekt zu gefährden. Wenn nach einem halben Jahr das Team zufrieden ist, wird weiter ausgebaut; wenn nicht, hat man wenig verloren.
Ein Zwischenstand
Ich habe nach wenigen Wochen nicht das Gefühl, Java ersetzen zu wollen. Es ist eher so, dass mir bei jedem Getter, den ich in Java schreibe, nun auffällt, wie viel Tipparbeit das ist. Vielleicht ist das der eigentliche Effekt neuer Sprachen: Man sieht die eigenen Gewohnheiten schärfer. Ob Kotlin langfristig mehr wird als eine interessante Alternative, entscheidet sich nicht an den Sprachfeatures, sondern daran, ob sich Teams finden, die damit über Jahre arbeiten wollen. Das wird sich in den nächsten ein, zwei Jahren zeigen.
Beitragsbild: eigene Collage mit Logos von Wikimedia Commons (Kotlin-Logo: JetBrains, gemeinfrei; Duke (Java-Maskottchen): sbmehta nach Vorlage von Sun Microsystems, BSD-Lizenz); die Marken gehören ihren Inhabern.
Christian Ackermann
Softwareentwickler (C++, C, Java, C#) aus der Oberpfalz, bloggt seit 2001 über Linux, Technik und Kochen.