Software Development

6 wichtige Gründe für Kotlin als Java-Nachfolger im Enterprise-Bereich

Du bist im Java-Enterprise-Bereich unterwegs und hast noch keine bis wenige Berührungspunkte mit Kotlin gehabt? Dann ist dieser Blogbeitrag besonders spannend für dich! Schließlich enthält er neben einer kurzen Vorstellung von Kotlin nicht weniger als 6 wichtige Punkte, die dir die Vorteile von Kotlin gegenüber Java aufzeigen. Legen wir los!

Was ist Kotlin?

Kotlin ist eine moderne, typisierte Programmiersprache. Die Entwicklung von Kotlin startete 2011 bei Jetbrains. Im Jahr 2016 erschien mit 1.0 die erste stabile Version. Der kompilierte Bytecode kann ohne Anpassungen von der JVM gelesen werden.

Geworben wird unter anderem mit

  • der schlanken und modernen Syntax und
  • dem Verhindern von Nullpointer-Fehlern.

Kotlin-Verbreitung

Seitdem Google neben Java und C++ auch Kotlin als "first-class"-Sprache für Mobile-Apps auf dem Android-Betriebssystem hervorgehoben hat, hat sich Kotlin bei Android-Entwicklern bereits einen Namen gemacht.

Bei der letzten Stackoverflow-Umfrage, im Januar 2018, erreichte Kotlin den zweiten Platz der „most loved” Programmiersprachen. Bei Github war Kotlin im Jahr 2018 sogar die am schnellsten wachsende Programmiersprache.

1. Kompatibilität

In Kotlin geschriebener Code kann aus Java-Klassen heraus angesprochen werden. Das bedeutet, dass nicht das gesamte Projekt in Kotlin umgeschrieben werden muss.

Stattdessen solltest du mit einem neuen Feature oder auch einer einzelnen Klasse in Kotlin anfangen und prüfen, ob weitere Anpassungen nötig sind.

Um Kotlin-Code zu kompilieren, stehen für Maven, Gradle und sogar Ant Plugins bereit.

Bei IntelliJ-Community und IntelliJ-Ultimate ist die Unterstützung bereits integriert. Auch für Eclipse ist ein offizielles Plugin vorhanden.

Beim Spring-Framework, das in der Enterprise-Entwicklung oft Verwendung findet, ist die Unterstützung seit Version 5 vorhanden (09.2017). Es war zwar bereits vorher möglich, Kotlin einzusetzen, jedoch mussten die Spring-Beans als open classes deklariert werden, um ein Ableiten durch die verwendete CGLib möglich zu machen. Das ist seit dem Erscheinen des Kotlin-Spring-Plugins nicht mehr notwendig.

2. Data-Klassen und Vermeidung von Boilerplate-Code

Das Hauptargument von Kotlin ist in meinen Augen, dass ein großer Teil des Java-Boilerplate-Codes vermieden werden kann.

In diesem Beispiel habe ich eine Java-Klasse für Mitarbeiter geschrieben. Sie enthält die Attribute ID, Vorname, Nachname, Einstellungsdatum sowie ein Flag „Aktiv”. Insgesamt sind das bei mir sage und schreibe 121 Zeilen Java-Code.

In Kotlin lässt sich die selbe Klasse in nur 7 Zeilen definieren! Das sieht dann folgendermaßen aus:

data class Employee(
  val id: String,
  var firstname: String? = null,
  var lastname: String? = null,
  var employedSince: Date,
  var active: Boolean = false
)

Nicht schlecht, oder?

Ähnlich wie Lombok kümmert sich Kotlin durch Verwendung einer Datenklasse (data class) darum, dass Methoden für toString(), hashCode() und copy() sowie Konstruktoren vorhanden sind.

Außerdem werden für den Zugriff aus Java die Getter und Setter in gewohnter Form generiert. Der Vorteil gegenüber Lombok besteht jedoch darin, dass dies nicht in die IDE integriert werden muss.

3. Mehr Sicherheit bei Nullpointern

Die übliche Nullwert-Überprüfung in Java hat meist zur Folge, dass vor dem Zugriff auf Variablen folgendes geprüft werden muss:

if(employee != null && employee.getLastname() != null){
  length = employee.getLastname().length()
}

 

In Kotlin kann man jedoch festlegen, ob ein Attribut nullable ist. Durch das Setzen eines Standardwertes kann die Überprüfung wegfallen:

val firstname: String = ""

 

Alternativ wird ein Nullwert erlaubt und vor der Anweisung geprüft, ob einer vorhanden ist:

val length?: Int = employee?.lastname?.length

 

Sollte in dieser Kette ein Wert null sein, ist das Endergebnis in unserer Variable length ebenfalls der Wert null, da es gar nicht erst zu einer Zuweisung kam. Das Ganze kann aber mit dem Elvis-Operator und einem Ersatzwert verhindert werden:

val length: Int = employee?.lastname?.length ?: 0

 

So haben wir in jedem Fall eine Länge und können in den nachfolgenden Zugriffen auf eine Überprüfung komplett verzichten. Der Compiler und die IDE weisen zudem schon vor dem Ausführen der Anwendung auf fehlende Nullchecks und Zuweisungen von null auf nicht nullfähige Variablen hin.

Das Prinzip ähnelt den Optionals aus Java, mit dem Unterschied, dass mit Kotlin eine deutlich schlankere Syntax möglich ist.

  • Java:
    lastname.ifPresent(value -> println(value.length()));
  • Kotlin:
    println(lastname?.length)

 

Im Fall eines Nullwertes wird auch "null" in die Konsole ausgegeben.

Dies kann mit einer Hilfsfunktion verhindert werden. Diese bietet auch die Möglichkeit, einfacher innerhalb des Blocks auf die Variable zuzugreifen:

lastname?.let {it ->
  println("Die Länge von >$it< ist: ${it.length}")
}

 

Hinter der let-Funktion verbirgt sich ein Lambda-Ausdruck mit dem Parameter it, der den Wert von lastname erhält. Der im Quellcodebeispiel kursiv geschriebene Teil sollte weggelassen werden und dient hier nur dem Verständnis. Das Fragezeichen hinter lastname garantiert, dass im Fall eines Nullwertes der Block gar nicht erst ausgeführt wird.

In der Zeichenkette des vorherigen Beispiels wurden auch String-Templates von Kotlin verwendet. Einfache Variablen können mit $var ausgewertet werden – nur für Ausdrücke sind geschweifte Klammern notwendig: ${it.length}.

Ist dir eigentlich schon aufgefallen, dass Semikola in Kotlin nicht mehr gebraucht werden?

4. Default-Parameter in Funktionen

In Kotlin ist es nicht mehr notwendig, Funktionen für Defaultwerte zu überladen. Die Defaultwerte werden direkt in der Parameterliste definiert.

  • Java:
    log(string value, Date timestamp){
      System.out.print("%s : %s", timestamp, value);
    }
    log(string value){
      print(value, new Date());
    }
  • Kotlin:
    fun log(value: String, timestamp: Date = Date()){
      print("$value : $timestamp")
    }

 

Sollten mehrere Parameter mit einem Defaultwert versehen sein, können wir auch beim Aufruf angeben, welcher Wert gesetzt werden soll. Hier ein Beispiel mit dem Employee von oben:

Employee(1, lastname = "Mustermann", isActive = false)
Employee(2, firstname = "Max", lastname = "Mustermann")

5. Überladen von Operatoren

Das aus C bekannte Überladen von Operatoren ist in Kotlin für viele weitere Operatoren möglich:

operator fun plus(other: Vector) = Vector(x + other.x, y + other.y)
val vector = Vector(3, 1) + Vector(4, 2)

6. Extension-Functions

Kotlins Extension-Functions zielen auf die in Java beliebten Utility-Klassen ab. Es ist nun zusätzlich möglich, jede beliebige Klasse um eigene Funktionen zu ergänzen.

fun String.double(value: String) : String{
  return value + value
}

 

Oder als Inline-Function:

fun String.double(value: String) = value + value

 

So ist statt  Utilities.double("Hi"); ein Aufruf direkt über den String möglich: "Hi".double()

Mögliches Risiko: Breaking-Changes & Stabilität

Die Hauptbestandteile der Sprache sind seit Version 1.0 als stable angesehen. Es werden folglich nicht mehr Breaking-Changes auftreten als in Java selbst.

Mehr dazu unter: https://kotlinlang.org/docs/reference/evolution/components-stability

Ausblick

Jetbrains verfolgt das Ziel, Kotlin auf allen Endgeräten und Plattformen zu etablieren, und bietet mit Kotlin/Native eine Möglichkeit für die Nutzung einer gemeinsamen, nativen Codebasis für die meistverwendeten Betriebssysteme:

  • iOS
  • MacOS
  • Android
  • Windows
  • Linux
  • Browser (Kotlin/JS)
  • WebAssembly

Kotlin/Native befindet sich zum aktuellen Zeitpunkt noch in der Entwicklung. Aus diesem Grund sollte es noch nicht produktiv eingesetzt werden.

Mehr dazu unter: https://kotlinlang.org/docs/reference/native-overview.html

Fazit

In der Vergangenheit wurde bereits mit Scala, Groovy und Clojure versucht, eine weitere JVM-Sprache zu etablieren. Es ist gut möglich, dass Kotlin durch Jetbrains Multi-Plattform-Entwicklungen und durch Googles Unterstützung einen größeren Erfolg erreichen wird.

Durch die hohe Stabilität und Kompatibilität von Kotlin ist es zudem mit geringem Risiko verbunden, einzelne Teile einer Java-Anwendung durch Kotlin zu ersetzen. Der Code ist für Java-Entwickler weiterhin ohne Probleme les- und wartbar.

Im Eclipse-Umfeld lohnt es sich, einen Blick auf Xtend zu werfen. Die meisten Features von Kotlin sind in ähnlicher Form verfügbar, und es gibt noch einige weitere interessante Ansätze.

Wie kann ich starten?

Du bist experimentierfreudig und möchtest erste eigene Erfahrungen mit Kotlin sammeln?

Auf den offiziellen Seiten von Kotlin gibt es einen webbasierten Sandkasten mit Beispielen und Übungen für dich. Mit Hilfe von Refactoring-Aufgaben werden dir dort alle Features von Kotlin gezeigt.

Viel Spaß beim Spielen!

Was denkst du? Hat Kotlin eine Chance, die Nachfolge von Java im Enterprise-Umfeld anzutreten? Ich freue mich über deinen Kommentar!

    
Über Karsten Knappe

Karsten Knappe ist IT-Berater und Entwickler bei der itemis AG in Lünen. Er arbeitet gerne an innovativen Themen und Technologien im Web- und Mobile-Bereich.