Praktisch mit Kotlin unterwegs

13.12.2019 Raffael Schneider
Tech Kotlin JVM Open source Hands-on Good-to-know

Kotlin ist eine plattformübergreifende, statisch typisierte Programmiersprache. Von Anfang an war Kotlin daraus ausgerichtet komplett interoperabel mit Java und dessen JVM zu sein. Kotlin wurde durch die multinationale Software-Unternehmen JetBrains, den Machern des etablierten IDE IntelliJ, entwickelt. In 2019 hat Google Kotlin als offizielle Entwicklersprache (preferred language) von Android-App-Entwicklung deklariert. Durch den Einsatz von heutigen Entwicklungserkenntnissen in Programmiersprachen eine komfortablere und pragmatischere Alternative zu Java zu bieten, die weiterhin zu 100%-kompatibel mit dem bisherigen Java-Ökosystem bleibt.

Hier eine kleine Auflistung aller Vorteile die Kotlin gegenüber Java und ähnlichen Sprachen birgt:

  • Kleinerer Footprint Kotlin’s Compiler erzeugt im Vergleich zu Java ähnlich grosse Bytecode
  • Interoperabilität Durch vollständige Kompatibilität mit dem Java-Stack lassen sich Kotlin-Klassen zusammen mit Java-Klassen in einem Projekt schreiben und warten
  • Skalierbarkeit Kotlin verfügt über native Koroutinierung und erlaubt somit die Entwicklung von skalierbaren Lösungen
  • Lernkurves: Obwohl Kotlin einen leicht anderen Syntax, Keywords und Funktionalitäten aufweist, so ist der Sprung von Java auf Kotlin durch intuitive Design-Features eine durchaus für Alle machbar
  • Lesbarkeit / Wartbarkeit Syntaktischer Zucker und sonstige Spracheigenschaften lassen den Code überschaubarer und somit wartbarer
  • Nicht nur für Android: Durch native Unterstützung von Spring Framework 5 seit Anfang 2017 ist Kotlin auch in der Entwicklung von ganzen Backend-Systemen vertretbar geworden.

Und so sieht Kotlin aus

Null-Check

Bevor wir uns zusammen in Real-World Kotlin-Code stürzen, lass uns zuerst als Vergleichsvorlage eine einfache Java-Klasse zu Betracht ziehen. Die callIfMatch()-Methode nimmt einen String-Parameter nullableString entgegen. Dieser Wert könnte bei der Übergabe an die Methode null sein, darum der Name nullableString. Das allererste, was die Methode tut, ist den Wert von nullableString in den Log-Output zu schreiben versucht. Dabei wird geprüft ob dessen Wert null ist, falls ja, wird der Wert von nullableString übergeben, falls nein einen Default-Wert von "defaultString". Danach wird über eine if-Schlaufe geprüft, ob der Wert von dem Methodenparameter mit "matchMe" übereinstimmt. Falls ja wird eine generischer call() aufgeruft. Dabei wird in der Schleife nochmals auf null geprüft. Diese Redundanz ist zu Vergleichszwecken so gewollt und nicht zwingend ungewöhnlich.

#####Java

public void callIfMatch(String nullableString) {
    Log.callerClass("callerClass", nullableString != null ? nullableString, "defaultString");    

    if (nullableString != null && nullableString.contains("matchMe"){
        call();
    }
}

Als Nächstes das Kotlin-Pendant zur obigen Java-Klasse mit identischer Funktionalität. Dabei merken wir sogleich, dass weniger Zeichen für äquivalente Business-Logik gebraucht wird. Die Methode callIfMatch() nimmt auch hier einen String-Parameter nullableString entgegen und deklariert explizit bei dessen Typenbestimmung String?, dass der Wert null sein könnte mit einem Fragezeichen. Nebenbei, dass die Typendeklaration für Java-Kenner ungewohnt nach dem Parameter-/Variablennamen kommt, so ist das Fragezeichen-Keyword intuitiv. Das sagt dem Compiler im Voraus, dass dieser Wert anders gehandhabt werden muss und während der Laufzeit null sein kann. Beim Aufruf des Wertes wird auch das Fragezeichen-Keyword dem Variablennamen hinzugefügt, um genau diese Möglichkeit explizit zu deklarieren. Der Compiler weiss dann zur Laufzeit wie damit umzugehen ist.

Kotlin
fun callIfMatch(nullableString: String?) {
    Log.callerClass("callerClass", nullableString ?: "defaultString")

    when(nullableString?.contains("matchMe")){
        true -> { call() }
    }
}

Mehrfachverzweigungen

Ein weiterer typischer Fall in der Real-World sind Fallunterscheidungen per if/else oder switch. Hier schauen wir uns den ersten Fall zur Veranschaulichung an. Die folgende showStatusText()-Methode gibt einen String-Wert zurück. Dieser wird anhand einer if/else mit fachlich unterschiedlichen Werten befüllt. Ausschlaggebend für die Fallunterscheidung ist des Instanztyps des someState-Objekts. Dieser kann hier wahlweise Connected, Connecting, Disconnected sein. Auf den Instanztyp wird in Java mit instanceof geprüft. Je nach Wert von text ergibt sich am Schluss einen anderen Rückgabewert von "Status: {Connected|Connecting|Disconnected}. Please take note!" .

Java
public String showStatusText() {
    String text = null;

    // Expecting only 3 different states
    if (someState instanceOf Connected) {
        text = "Client connected.";
    } else if (someState instanceOf Connecting){
        text = "Connecting..."
    } else if (someState instanceOf Disconnected){
        text = "Not Connected."
    }

    return "Status: " + text + ". Please take note!"
}

Genau wie beim vorherigen Beispiel merkt man, dass für die äquivalente Logik weniger Zeichen gebraucht werden und der ganze Code somit leaner wirkt. In Kotlin werden für diesen Fall andere Keywords genutzt und von einer leicht anderen Variablenzuweisung Gebrauch macht. Der Variable text wird direkt einen Wert zugewiesen, der dem Rückgabewert von when entspricht. Dieser when-Ausdruck prüft den Zustand von someState und entscheiden somit über die Fallunterscheidung welcher Wert an text zugewiesen werden kann. Zudem interessant ist wie der ganze String am Ende zusammengesetzt wird. Anstatt mehrere Strings per + zu konkatenieren kann über $ direkt der Wert der Variable im String ausgespielt werden.

Kotlin
fun showStatusText() {
    val text = when(someState) {
        is Connected -> "Client connected."
        is Connecting -> "Connecting..."
        is Disconnected -> "Not Connected."
    }

    return "Status: $text Please take note!"
}

Wir hoffen, dass wir mit diesen zwei konkreten Beispielen die Schlankheit und intuitive Nutzung von Best Practices von modernen Programmiersprachen wie Kotlin veranschaulicht werden konnte. Solche Features erleichtern das Schreiben, das Lesen und besonderes das Warten von einer Codebase immens.

Probieren Sie es gleich selber aus

Falls wir es geschafft haben Ihnen Kotlin näherzubringen und Sie das Bedürfnis haben gleich selber Hand anzulegen, so sei gesagt dass es eine Vielzahl von Online-Umgebungen gibt worin Kotlin gleich geschrieben und ausprobiert werden kann. Einer dieser Online-Umgebungen ist die Kotlin Spielwiese, auf Englisch Kotlin Playground genannt. Dabei wird gleich per Web-Applikation der Code kompiliert und ausgeführt:

Kotlin Playground

Falls Sie weitere Fragen zu Kotlin haben sollten, wir bei b-nova setzen Wert auf Innovation durch neue Technologien und scheuen uns nicht neue Programmiersprachen wie Kotlin anzuwenden und in Ihrem Projekt einzusetzen.

Weiterführende Links:

Ktor Framework | Build Asynchronous Servers and Clients in Kotlin

Spring Boot | Building web applications with Spring Boot and Kotlin

Raffael Schneider – Crafter, Disruptor, Freigeist. Als begeisteter GitOps-Enthusiast schreibt Raffael gerne über Programmiersprachen, Themen rund um DevOps und hat ein Faible für die neusten IT-Hypes aller Art.