© Visual Generation/Shutterstock.com
Eine Einführung in die moderne Programmiersprache Kotlin

Kotlin – das bessere Java?


Kotlin ist eine Programmiersprache, die im Februar 2016 in Version 1.0 das Licht der Welt erblickt hat. Im Jahr 2019 hat Google Kotlin zum „First-class Citizen“ der Android-Entwicklung erklärt und ihr damit zum Durchbruch verholfen. Doch was macht eigentlich Kotlin besonders und wieso lohnt sich ein Blick darauf auch für alte Java-Hasen, die nichts mit Android zu tun haben? Diese und weitere Fragen behandle ich in diesem Artikel.

Eines gleich vorweg: Ich bin kein Kotlin-Fanboy und finde Java als Programmiersprache sehr gelungen. Meine tägliche Arbeit dreht sich vor allem um die Backend-Entwicklung auf der JVM, hauptsächlich in Java. Allerdings bin ich der Meinung, dass man auch öfter mal über den Tellerrand blicken und sich mit neueren Sprachen auf der JVM beschäftigen darf. Dieser Artikel geht davon aus, dass Sie bereits Java „sprechen“, und zeigt interessante Features von Kotlin aus dieser Sicht. Ich konzentriere mich dabei auf die meiner Meinung nach wichtigsten Features von Kotlin: Funktionen, Variablen, null safety, objektorientierte Programmierung, funktionale Programmierung und Interoperabilität mit Java.

Kotlin wird als Open-Source-Software unter der Apache-2.0-Lizenz von der Firma JetBrains entwickelt. Das ist die Firma, die auch die bekannte IDE IntelliJ IDEA vertreibt und entsprechend gut ist dort auch die Unterstützung für Kotlin. Es gibt aber auch Plug-ins für Eclipse und NetBeans. Kotlin wird bereits seit 2010 entwickelt, allerdings erlangte es erst 2016 mit Version 1.0 einige Bekanntheit. Der endgültige Durchbruch, zumindest in der Android-Entwicklung, kam 2019, als Google auf der Google I/O die Android-Entwicklung „Kotlin-first“ deklariert hat.

Kotlin ist eine moderne, statisch typisierte Programmiersprache, die Konzepte aus der objektorientierten und der funktionalen Programmierung vereint. Ein besonderes Augenmerk liegt auf der Kompatibilität mit Java-Code – dies ist auch eines der Differenzierungsmerkmale von Kotlin gegenüber Scala. Entwickler können in Kotlin problemlos Java-Bibliotheken verwenden und müssen dabei auch nicht Datentypen, wie z. B. Listen, konvertieren. Ebenso ist es möglich, aus Java heraus Kotlin-Code zu verwenden. Der Kotlin-Compiler erzeugt Bytecode für die JVM (Java Virtual Machine) – d. h. Programme, die in Kotlin geschrieben sind, können mit einer handelsüblichen Java-Installation ausgeführt werden. Es wird nur eine JVM in mindestens Version 1.6 benötigt.

Kotlin selbst vermarktet sich im Vergleich zu Java als „concise“, also ohne viel so genannten Boilerplate-Code. Kotlin-Code ist um ca. 40 Prozent kürzer als vergleichbarer Java-Code und damit ausdrucksstärker [1]. Außerdem hat Kotlin ein verbessertes Typsystem, das vor allem darauf abzielt, NullPointerExceptions zu vermeiden. Aber schauen wir uns diese Versprechen doch einmal genauer an.

Hello World, in Kotlin

Wir beginnen klassisch mit „Hello World“:

package javamagazin fun main(args: Array<String>) { print("Hello world") }

Genau wie Java ist Kotlin-Code in Packages verwaltet. Was in obigem Beispiel sofort auffällt: Es ist nicht notwendig, eine Klasse zu erstellen, um die main-Funktion zu definieren. Funktionen werden mit dem Keyword fun deklariert (kurz für „function“). Bei den Parametern wird zuerst der Name des Parameters (args), danach dessen Typ (Array<String>) angegeben. Es ist also genau umgekehrt zu Java. Arrays werden als generische Typen ausgedrückt und nicht, wie in Java, mit eckigen Klammern hinter dem Typ (z. B. String[]).

Im Funktions-Body benötigt man hinter den Statements keine Semikola, sie sind in Kotlin optional. In der Funktion findet sich nun ein Funktionsaufruf von print(...) ohne Objektinstanz. Es ist in Kotlin also möglich, Funktionen ohne zugehörige Objektinstanz aufzurufen. In der Standardbibliothek gibt es mehrere Funktionen, die keiner Klasse angehören. print(...) ist hier eine Abkürzung für System.out.print(…), das einem vermutlich bekannt vorkommt. Führt man diesen Code aus, erscheint auf der Konsole wie erwartet „Hello World“.

Typinferenz und Funktionen

In Listing 1 werden Variablen mit dem Keyword val deklariert. Den Typ der Variablen kann Kotlin automatisch per Typinferenz bestimmen (in diesem Fall Int, das Kotlin-Äquivalent zu Javas int). Wem das nicht gefällt, der kann den Typ getrennt mit einem Doppelpunkt explizit angeben: val operand1: Int = 1. Variablen, die mit val definiert werden, sind automatisch unveränderlich (immutable), ähnlich wie final in Java. Eine weitere Zuweisung würde einen Compilerfehler auslösen. Das ist ein wichtiges Konzept in Kotlin: Man sollte so viel wie möglich unveränderlich machen.

Listing 1

fun main(args: Array<String>) { val operand1 = 1 val operand2 = 2 val sum = operand1 + operand2 print("$operand1 + $operand2 = $sum") }

Die Typinferenz funktioniert auch, wenn mehrere Variablen zusammen verwendet werden – im Beispiel bestimmt der Ergebnistyp des +-Operators den Typ der Variablen sum (Int).

Im print(...)-Statement habe ich ein weiteres Feature von Kotlin verwendet, die sogenannte Stringinterpolation, die die Variablen operand1, operand2 und sum in einen String einbettet. Wenn das Programm ausgeführt wird, erscheint auf der Konsole 1 + 2 = 3.

Listing 2

private fun sum(operand1: Int, operand2: Int = 0): Int = operand1 + operand2 fun main(args: Array<String>) { val result1 = sum(1, 2) println("1 + 2 = $result1") val result2 = sum(1) println("1 + 0 = $result2") }

In der ersten Zeile in Listing 2 ist eine Funktion namens sum deklariert. Der Modifier private gibt an, dass die Funktion nur in derselben Datei verwendet werden kann. Außerdem ist der Rückgabetyp der Funktion mit angegeben, hier Int. Den Rückgabetyp gibt man mit einem Doppelpunkt nach der Parameterdeklaration an. Im Beispiel ist auch die Kurzschreibweise für Funktionen verwendet, die auf geschweifte Klammern verzichtet und direkt mit = hinter der Signatur eingeleitet wird. Diese Schreibweise kann für alle Funktionen verwendet werden, die nur aus einer Zeile Code bestehen. Der Parameter operand2 ist außerdem standardmäßig auf 0 gesetzt, d. h., dass der Aufrufer ihn nicht explizit angeben muss. Optionale Parameter sind sicherlich ein Feature, das sich viele Java-Entwickler schon immer gewünscht haben.

In der main-Funktion sieht man den Aufruf von sum zuerst mit explizit gesetzten Argumenten 1 und 2. Der zweite Aufruf der Funktion sum lässt das zweite Argument weg, sodass der Standardwert des Parameters (0) verwendet wird. Wenn dieser Code ausgeführt wird, zeigt die Konsole

1 + 2 = 3 1 + 0 = 1

Null Safety

Das in meinen Augen beste Feature von Kotlin ist das verbesserte null-Handling. Ein oft gesehener Fehler bei (Java-)Programmen ist die NullPointerException. Sie tritt auf, wenn eine Variable null enthält, der Entwickler den Fall aber nicht behandelt hat und trotzdem auf die Variable zugreift. Kotlin verhindert dies durch eine Erweiterung des Typsystems: nullable Variablen haben einen anderen Typ als Variablen, die nicht null sein können. An einem Beispiel wird das anschaulicher.

Listing 3

fun formatName(firstName: String, midName: String?, lastName: String): String...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang