loading=”lazy” width=”400px”>In gewisser Weise ist Kotlin “mehr Java” als Java selbst.Trismegist san | shutterstock.com Kotlin ist eine ausdrucksstarke, prägnante Sprache mit ausgeprägtem Support für funktionale Programmierung – und nach Java die zweitbeliebteste JVM-Sprache. Dass Kotlin vollständig mit Java kompatibel ist, macht die Programmiersprache insbesondere für Java-Entwickler attraktiv. Kotlin ergänzt und erweitert die Möglichkeiten, die Java bietet und stellt innerhalb des JVM-Ökosystems eine performante Komponente dar. Das Beste daran: Kotlin zu erlernen, verlangt überlasteten Dev-Gehirnen nicht allzu viel ab, wenn letztere bereits mit Java vertraut sind. In diesem Tutorial werfen wir einen eingehenden Blick auf die Dynamik, die Kotlin in der Entwicklungspraxis entfaltet. Erste Schritte mit Kotlin Wie bei Java muss auch bei Kotlin ein JDK installiert sein. Das Kommandozeilen-Tool SDKMan vereinfacht es, Kotlin zu installieren und zu managen: $ sdk install kotlin 2.0.20 $ kotlin -version Kotlin version 2.0.20-release-327 (JRE 23-ea+24-1995) Nach der Installation können Sie eine simple Main.kt-Datei erstellen und ausführen: // Main.kt fun main() { println(“Hello, InfoWorld!”) } Um sie zu kompilieren, nutzen Sie folgenden Befehl: $ kotlinc Main.kt Der Output ist MainKt.class. Dieses Class-File führen Sie wie jedes andere aus: $ java MainKt Hello, Kotlin! Zu beachten ist dabei, dass eine Funktion ohne Rückgabewert (wie die obige), keinen ungültigen Rückgabewert wie in Java deklariert. Stattdessen gibt es überhaupt keinen Return Modifier. Im Gegensatz zu Java können Sie eine Funktion mit dem Keyword fun auch außerhalb einer Klasse deklarieren. In einfachen Fällen lassen Funktionen sämtliche Merkmale vermissen, die in Java zu finden sind: kein Package, kein Class-Name und keine Public Static Void Qualifier. Kotlin verfügt zwar über diese Funktionen, verbirgt diese jedoch per Default und nutzt Konventionen, um von vorneherein eine einfachere Syntax bereitzustellen. Davon abgesehen ist es nicht üblich, Kotlin direkt mit Java-Tools auszuführen. Das oben angeführte Beispiel macht jedoch die Beziehung zwischen Kotlin und Java deutlich. Normalerweise würden Sie mit der kotlin-Laufzeitumgebung oder einem Build-Tool wie Gradle arbeiten. Dazu später mehr. First-Class-Funktionen in Kotlin Kotlin ist eine funktionale Sprache erster Klasse: Indem sie ermöglicht, Funktionsreferenzen aus anderen Funktionen zu übergeben oder zurückzugeben, bietet sie enorme Flexibilität. Oft ist es auch möglich, Java- und Kotlin-Code „zusammenzubringen“: // Main.kt fun main() { System.out.println(“Hello from Java, InfoWorld!”); println(“Hello, InfoWorld!”) } Auf der anderen Seite gibt es jedoch einige Syntax-Unterschiede bei Kotlin, die dazu führen können, dass Java-Standards ungültig werden. Zum Beispiel erlaubt die Sprache keine primitiven Typen. In dieser Hinsicht ist Kotlin fast mehr Java als Java selbst: Hier ist wirklich alles ein Objekt – es gibt keine int-, long-, double– oder char-Ausnahmen (mit Project Valhalla bewegt sich Java in eine ganz ähnliche Richtung). Zudem unterscheidet Kotlin strikt zwischen veränderbaren und unveränderbaren Variablen – was einen allgemeinen Trend in modernen Programmiersprachen abbildet. Dabei stellt val eine unveränderbare, var eine veränderbare Variable dar: val myValInt: Int = 10; var myVarInt: Int = 10 // myValInt++; Aufmerksame Leser haben längst bemerkt, dass Semikolons in Kotlin wie in JavaScript optional sind. Generell ist es unter Kotlin-Devs üblich, auf abschließende Semikolons zu verzichten. Typen inferenziert Kotlin folgendermaßen: val myString = “FooBar”; println(“My string ${myString} is a classic.”); Dieses Code-Snippet demonstriert auch den in Kotlin integrierten Support für String-Interpolation, dessen Syntax der vieler Templating-Tools ähnelt. ${} kann dabei auch Expressions beinhalten (beispielsweise ${myString.upperCase()}). Enthält der Variablenname keine Sonderzeichen, können Sie auch auf eine vereinfachte Form zurückgreifen: println(“When in doubt, $myString.”); Unterfüttert wird das alles vom Typ-System von Java, auf das Sie folgendermaßen zugreifen: println(myString::class.java.typeName); // Outputs “String” Null-Handling mit Kotlin Die NullPointerException stellt eine der bekanntesten Ausnahmen in Java dar. Bei Kotlin sind Variablen standardmäßig nicht „nullbar“: Der Compiler verhindert es, normale Variablen auf null zu setzen. Sollten Sie darauf Wert legen, können Sie das folgendermaßen ändern: val myNullableString: String? = null Um mit Nullwerten umzugehen, verfügt Kotlin auch über den .?– und :?-Operator. Erstgenannter funktioniert ähnlich wie der optionale Chaining-Operator, um den JavaScript vor kurzem ergänzt wurde. Er ermöglicht einen „Short Circuit“ auf Nullwerte ohne ausführliche Überprüfungen: possiblyNull.?possiblyNullMember.?anotherMember Wenn einer der Teile null ist, gibt der gesamte Ausdruck null zurück, ohne einen Fehler aufzuwerfen. Mit dem Nullish Coalescing Operator 😕 ist es möglich, die linke Seite auf null zu testen und sie zurückgeben, wenn sie nicht null ist. Anderenfalls wird die rechte Seite zurückgegeben, die ebenfalls null sein kann: something 😕 somethingElse Wenn something null ist, erhalten Sie somethingElse. Collections in Kotlin Um mit Variablensammlungen zu arbeiten, verfügt Kotlin über Sets, Listen und Maps. Diese ermöglichen sowohl veränderbare als auch unveränderbare Varianten. Für eine veränderbare String-Liste würden Sie auf folgenden Befehl zurückgreifen: import kotlin.collections.*; fun main() { val books: MutableList = mutableListOf(“Autobiography of a Yogi”, “Slaughterhouse Five”, “Phaedrus”); println(books[2]); } Wie Sie sehen, haben wir die Collections-Bibliothek importiert. Weil diese in der Kotlin-Standardbibliothek enthalten ist, können wir sie kompilieren: $ kotlinc Main.kt Dieser Versuch führt allerdings zu einem Fehler: $ java MainKt Exception in thread “main” java.lang.NoClassDefFoundError: kotlin/collections/CollectionsKt at MainKt.main(Main.kt:14) at MainKt.main(Main.kt) Caused by: java.lang.ClassNotFoundException: kotlin.collections.CollectionsKt at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528) Hierbei handelt es sich um eine aus Java bekannte Fehlermeldung, die darüber Auskunft gibt, dass für CollectionsKt keine Klassendefinition vorhanden ist. Um das zu umgehen, binden Sie die Standard-Bibliothek folgendermaßen zur Laufzeit ein: $ java -cp /home/matthewcarltyson/kotlin:/home/matthewcarltyson/.sdkman/candidates/kotlin/current/lib/kotlin-stdlib.jar MainKt Phaedrus Dieser Befehl weist Java an, kotlin-stdlib.jar einzubinden. Eine andere Möglichkeit besteht darin, die Kotlin-Laufzeitumgebung zu nutzen, um stdlib automatisch einzubinden: $ kotlin MainKt Auf Listen greifen Sie wie auf Arrays zu – indem Sie Klammern verwenden: println(books[2]) // outputs “Phaedrus” Gradle mit Kotlin nutzen Die einfachste Möglichkeit, Gradle und Kotlin zusammen zu nutzen: Starten Sie ein neues Projekt mit gradle init. Dieser Befehl ruft einen interaktiven Fragebogen über die Kommandozeile auf: $ gradle init Select type of project to generate: 2: application Select implementation language: 4: Kotlin Split functionality across multiple subprojects?: 1: no – only one application project Select build script DSL: 2: Kotlin Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]: no Project name (default: kotlin): kotlin Source package (default: kotlin): com.infoworld Dieses simple Programm können Sie nun über das Stammverzeichnis des Projekts ausführen: $ ./gradlew run Anschließend erhalten Sie ein „Hello, World“. So ist das Projekt aufgebaut: /settings.gradle.kts – Global settings for Gradle /app/ build.gradle.kts – The build file /app/src/main/kotlin/com/infoworld/App.kt – The single source file Werfen wir nun einen Blick auf die App.kt-Datei: package com.infoworld class App { val greeting: String get() { return “Hello World!” } } fun main() { println(App().greeting) } In diesem Beispiel finden sich einige Features, die wir noch nicht behandelt haben. Darunter auch eine Package Declaration (die Package- und Verzeichnis-Struktur müssen in Kotlin nicht strikt übereinstimmen). Zudem sehen Sie hier die optimierte Kotlin-Syntax, um Klassen zu deklarieren. Per Default sind Klassen bei Kotlin öffentlich sichtbar – App ist also eine Public Class. Innerhalb dieser befindet sich ein read-only String-Member namens greeting. Dabei ist zu beachten, dass die greeting-Property eine get()-Funktion deklariert. Diese wird ausgeführt, wenn Sie den Dot-Operator nutzen, um darauf zuzugreifen. Im Folgenden versuchen wir uns an einem anspruchsvolleren Beispiel und laden die Charakter-Daten für Chewbacca über die Star-Wars-API herunter. Die App.kt-Datei lässt sich wie folgt ändern: //app/src/main/kotlin/com/infoworld/App.kt package com.infoworld import com.google.gson.Gson import java.net.URL class App { fun fetchAndPrintCharacterInfo(url: String) { val gson = Gson() val response = URL(url).readText() val character = gson.fromJson(response, StarWarsCharacter::class.java) println(“Name: ${character.name}”) println(“Height: ${character.height}”) } } data class StarWarsCharacter( val name: String, val height: String, ) fun main() { val chewbaccaUrl = “https://swapi.dev/api/people/13/” val app = App() app.fetchAndPrintCharacterInfo(chewbaccaUrl) } Dieses Snippet gewährt einen Einblick in Kotlins Data Class, die darauf konzipiert ist, Informationen zu speichern (ähnlich wie Value Objects in Java). Die StarWarsCharacter-Klasse verfügt über alle Standardmethoden wie Getter und Setter, hashCode, toString und equals. Das ist ideal, um die API-Daten in einen Container zu entpacken – was wir nun tun. Ergänzen Sie den dependencies-Abschnitt in /app/build.gradle.kts um folgende Abhängigkeiten: implementation(“com.google.code.gson:gson:2.9.1”) Das ermöglicht, die JSON-Daten von der API zu verarbeiten. Wenn Sie die Anwendung nun ausführen, sehen Sie einige Informationen über Chewbacca: $ ./gradlew run > Task :app:run Name: Chewbacca Height: 228 Hair color: null Eye color: null BUILD SUCCESSFUL in 2s (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
Kotlin-Tutorial für Java-Entwickler
loading="lazy" width="400px">In gewisser Weise ist Kotlin “mehr Java” als Java selbst.Trismegist san | shutterstock.com Kotlin ist eine ausdrucksstarke, prägnante Sprache mit ausgeprägtem Support für funktionale Programmierung – und nach Java die zweitbeliebteste JVM-Sprache. Dass Kotlin vollständig mit Java kompatibel ist, macht die Programmiersprache insbesondere für Java-Entwickler attraktiv. Kotlin ergänzt und erweitert die Möglichkeiten, die Java bietet und stellt innerhalb des JVM-Ökosystems eine performante Komponente dar. Das Beste daran: Kotlin zu erlernen, verlangt überlasteten Dev-Gehirnen nicht allzu viel ab, wenn letztere bereits mit Java vertraut sind. In diesem Tutorial werfen wir einen eingehenden Blick auf die Dynamik, die Kotlin in der Entwicklungspraxis entfaltet. Erste Schritte mit Kotlin Wie bei Java muss auch bei Kotlin ein JDK installiert sein. Das Kommandozeilen-Tool SDKMan vereinfacht es, Kotlin zu installieren und zu managen: $ sdk install kotlin 2.0.20 $ kotlin -version Kotlin version 2.0.20-release-327 (JRE 23-ea+24-1995) Nach der Installation können Sie eine simple Main.kt-Datei erstellen und ausführen: // Main.kt fun main() { println("Hello, InfoWorld!") } Um sie zu kompilieren, nutzen Sie folgenden Befehl: $ kotlinc Main.kt Der Output ist MainKt.class. Dieses Class-File führen Sie wie jedes andere aus: $ java MainKt Hello, Kotlin! Zu beachten ist dabei, dass eine Funktion ohne Rückgabewert (wie die obige), keinen ungültigen Rückgabewert wie in Java deklariert. Stattdessen gibt es überhaupt keinen Return Modifier. Im Gegensatz zu Java können Sie eine Funktion mit dem Keyword fun auch außerhalb einer Klasse deklarieren. In einfachen Fällen lassen Funktionen sämtliche Merkmale vermissen, die in Java zu finden sind: kein Package, kein Class-Name und keine Public Static Void Qualifier. Kotlin verfügt zwar über diese Funktionen, verbirgt diese jedoch per Default und nutzt Konventionen, um von vorneherein eine einfachere Syntax bereitzustellen. Davon abgesehen ist es nicht üblich, Kotlin direkt mit Java-Tools auszuführen. Das oben angeführte Beispiel macht jedoch die Beziehung zwischen Kotlin und Java deutlich. Normalerweise würden Sie mit der kotlin-Laufzeitumgebung oder einem Build-Tool wie Gradle arbeiten. Dazu später mehr. First-Class-Funktionen in Kotlin Kotlin ist eine funktionale Sprache erster Klasse: Indem sie ermöglicht, Funktionsreferenzen aus anderen Funktionen zu übergeben oder zurückzugeben, bietet sie enorme Flexibilität. Oft ist es auch möglich, Java- und Kotlin-Code „zusammenzubringen“: // Main.kt fun main() { System.out.println("Hello from Java, InfoWorld!"); println("Hello, InfoWorld!") } Auf der anderen Seite gibt es jedoch einige Syntax-Unterschiede bei Kotlin, die dazu führen können, dass Java-Standards ungültig werden. Zum Beispiel erlaubt die Sprache keine primitiven Typen. In dieser Hinsicht ist Kotlin fast mehr Java als Java selbst: Hier ist wirklich alles ein Objekt – es gibt keine int-, long-, double– oder char-Ausnahmen (mit Project Valhalla bewegt sich Java in eine ganz ähnliche Richtung). Zudem unterscheidet Kotlin strikt zwischen veränderbaren und unveränderbaren Variablen – was einen allgemeinen Trend in modernen Programmiersprachen abbildet. Dabei stellt val eine unveränderbare, var eine veränderbare Variable dar: val myValInt: Int = 10; var myVarInt: Int = 10 // myValInt++; Aufmerksame Leser haben längst bemerkt, dass Semikolons in Kotlin wie in JavaScript optional sind. Generell ist es unter Kotlin-Devs üblich, auf abschließende Semikolons zu verzichten. Typen inferenziert Kotlin folgendermaßen: val myString = "FooBar"; println("My string ${myString} is a classic."); Dieses Code-Snippet demonstriert auch den in Kotlin integrierten Support für String-Interpolation, dessen Syntax der vieler Templating-Tools ähnelt. ${} kann dabei auch Expressions beinhalten (beispielsweise ${myString.upperCase()}). Enthält der Variablenname keine Sonderzeichen, können Sie auch auf eine vereinfachte Form zurückgreifen: println("When in doubt, $myString."); Unterfüttert wird das alles vom Typ-System von Java, auf das Sie folgendermaßen zugreifen: println(myString::class.java.typeName); // Outputs “String” Null-Handling mit Kotlin Die NullPointerException stellt eine der bekanntesten Ausnahmen in Java dar. Bei Kotlin sind Variablen standardmäßig nicht „nullbar“: Der Compiler verhindert es, normale Variablen auf null zu setzen. Sollten Sie darauf Wert legen, können Sie das folgendermaßen ändern: val myNullableString: String? = null Um mit Nullwerten umzugehen, verfügt Kotlin auch über den .?– und :?-Operator. Erstgenannter funktioniert ähnlich wie der optionale Chaining-Operator, um den JavaScript vor kurzem ergänzt wurde. Er ermöglicht einen „Short Circuit“ auf Nullwerte ohne ausführliche Überprüfungen: possiblyNull.?possiblyNullMember.?anotherMember Wenn einer der Teile null ist, gibt der gesamte Ausdruck null zurück, ohne einen Fehler aufzuwerfen. Mit dem Nullish Coalescing Operator :? ist es möglich, die linke Seite auf null zu testen und sie zurückgeben, wenn sie nicht null ist. Anderenfalls wird die rechte Seite zurückgegeben, die ebenfalls null sein kann: something :? somethingElse Wenn something null ist, erhalten Sie somethingElse. Collections in Kotlin Um mit Variablensammlungen zu arbeiten, verfügt Kotlin über Sets, Listen und Maps. Diese ermöglichen sowohl veränderbare als auch unveränderbare Varianten. Für eine veränderbare String-Liste würden Sie auf folgenden Befehl zurückgreifen: import kotlin.collections.*; fun main() { val books: MutableList = mutableListOf("Autobiography of a Yogi", "Slaughterhouse Five", "Phaedrus"); println(books[2]); } Wie Sie sehen, haben wir die Collections-Bibliothek importiert. Weil diese in der Kotlin-Standardbibliothek enthalten ist, können wir sie kompilieren: $ kotlinc Main.kt Dieser Versuch führt allerdings zu einem Fehler: $ java MainKt Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/collections/CollectionsKt at MainKt.main(Main.kt:14) at MainKt.main(Main.kt) Caused by: java.lang.ClassNotFoundException: kotlin.collections.CollectionsKt at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528) Hierbei handelt es sich um eine aus Java bekannte Fehlermeldung, die darüber Auskunft gibt, dass für CollectionsKt keine Klassendefinition vorhanden ist. Um das zu umgehen, binden Sie die Standard-Bibliothek folgendermaßen zur Laufzeit ein: $ java -cp /home/matthewcarltyson/kotlin:/home/matthewcarltyson/.sdkman/candidates/kotlin/current/lib/kotlin-stdlib.jar MainKt Phaedrus Dieser Befehl weist Java an, kotlin-stdlib.jar einzubinden. Eine andere Möglichkeit besteht darin, die Kotlin-Laufzeitumgebung zu nutzen, um stdlib automatisch einzubinden: $ kotlin MainKt Auf Listen greifen Sie wie auf Arrays zu – indem Sie Klammern verwenden: println(books[2]) // outputs “Phaedrus” Gradle mit Kotlin nutzen Die einfachste Möglichkeit, Gradle und Kotlin zusammen zu nutzen: Starten Sie ein neues Projekt mit gradle init. Dieser Befehl ruft einen interaktiven Fragebogen über die Kommandozeile auf: $ gradle init Select type of project to generate: 2: application Select implementation language: 4: Kotlin Split functionality across multiple subprojects?: 1: no - only one application project Select build script DSL: 2: Kotlin Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]: no Project name (default: kotlin): kotlin Source package (default: kotlin): com.infoworld Dieses simple Programm können Sie nun über das Stammverzeichnis des Projekts ausführen: $ ./gradlew run Anschließend erhalten Sie ein „Hello, World“. So ist das Projekt aufgebaut: /settings.gradle.kts - Global settings for Gradle /app/ build.gradle.kts - The build file /app/src/main/kotlin/com/infoworld/App.kt - The single source file Werfen wir nun einen Blick auf die App.kt-Datei: package com.infoworld class App { val greeting: String get() { return "Hello World!" } } fun main() { println(App().greeting) } In diesem Beispiel finden sich einige Features, die wir noch nicht behandelt haben. Darunter auch eine Package Declaration (die Package- und Verzeichnis-Struktur müssen in Kotlin nicht strikt übereinstimmen). Zudem sehen Sie hier die optimierte Kotlin-Syntax, um Klassen zu deklarieren. Per Default sind Klassen bei Kotlin öffentlich sichtbar – App ist also eine Public Class. Innerhalb dieser befindet sich ein read-only String-Member namens greeting. Dabei ist zu beachten, dass die greeting-Property eine get()-Funktion deklariert. Diese wird ausgeführt, wenn Sie den Dot-Operator nutzen, um darauf zuzugreifen. Im Folgenden versuchen wir uns an einem anspruchsvolleren Beispiel und laden die Charakter-Daten für Chewbacca über die Star-Wars-API herunter. Die App.kt-Datei lässt sich wie folgt ändern: //app/src/main/kotlin/com/infoworld/App.kt package com.infoworld import com.google.gson.Gson import java.net.URL class App { fun fetchAndPrintCharacterInfo(url: String) { val gson = Gson() val response = URL(url).readText() val character = gson.fromJson(response, StarWarsCharacter::class.java) println("Name: ${character.name}") println("Height: ${character.height}") } } data class StarWarsCharacter( val name: String, val height: String, ) fun main() { val chewbaccaUrl = "https://swapi.dev/api/people/13/" val app = App() app.fetchAndPrintCharacterInfo(chewbaccaUrl) } Dieses Snippet gewährt einen Einblick in Kotlins Data Class, die darauf konzipiert ist, Informationen zu speichern (ähnlich wie Value Objects in Java). Die StarWarsCharacter-Klasse verfügt über alle Standardmethoden wie Getter und Setter, hashCode, toString und equals. Das ist ideal, um die API-Daten in einen Container zu entpacken – was wir nun tun. Ergänzen Sie den dependencies-Abschnitt in /app/build.gradle.kts um folgende Abhängigkeiten: implementation("com.google.code.gson:gson:2.9.1") Das ermöglicht, die JSON-Daten von der API zu verarbeiten. Wenn Sie die Anwendung nun ausführen, sehen Sie einige Informationen über Chewbacca: $ ./gradlew run > Task :app:run Name: Chewbacca Height: 228 Hair color: null Eye color: null BUILD SUCCESSFUL in 2s (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
Kotlin-Tutorial für Java-Entwickler loading="lazy" width="400px">In gewisser Weise ist Kotlin “mehr Java” als Java selbst.Trismegist san | shutterstock.com Kotlin ist eine ausdrucksstarke, prägnante Sprache mit ausgeprägtem Support für funktionale Programmierung – und nach Java die zweitbeliebteste JVM-Sprache. Dass Kotlin vollständig mit Java kompatibel ist, macht die Programmiersprache insbesondere für Java-Entwickler attraktiv. Kotlin ergänzt und erweitert die Möglichkeiten, die Java bietet und stellt innerhalb des JVM-Ökosystems eine performante Komponente dar. Das Beste daran: Kotlin zu erlernen, verlangt überlasteten Dev-Gehirnen nicht allzu viel ab, wenn letztere bereits mit Java vertraut sind. In diesem Tutorial werfen wir einen eingehenden Blick auf die Dynamik, die Kotlin in der Entwicklungspraxis entfaltet. Erste Schritte mit Kotlin Wie bei Java muss auch bei Kotlin ein JDK installiert sein. Das Kommandozeilen-Tool SDKMan vereinfacht es, Kotlin zu installieren und zu managen: $ sdk install kotlin 2.0.20 $ kotlin -version Kotlin version 2.0.20-release-327 (JRE 23-ea+24-1995) Nach der Installation können Sie eine simple Main.kt-Datei erstellen und ausführen: // Main.kt fun main() { println("Hello, InfoWorld!") } Um sie zu kompilieren, nutzen Sie folgenden Befehl: $ kotlinc Main.kt Der Output ist MainKt.class. Dieses Class-File führen Sie wie jedes andere aus: $ java MainKt Hello, Kotlin! Zu beachten ist dabei, dass eine Funktion ohne Rückgabewert (wie die obige), keinen ungültigen Rückgabewert wie in Java deklariert. Stattdessen gibt es überhaupt keinen Return Modifier. Im Gegensatz zu Java können Sie eine Funktion mit dem Keyword fun auch außerhalb einer Klasse deklarieren. In einfachen Fällen lassen Funktionen sämtliche Merkmale vermissen, die in Java zu finden sind: kein Package, kein Class-Name und keine Public Static Void Qualifier. Kotlin verfügt zwar über diese Funktionen, verbirgt diese jedoch per Default und nutzt Konventionen, um von vorneherein eine einfachere Syntax bereitzustellen. Davon abgesehen ist es nicht üblich, Kotlin direkt mit Java-Tools auszuführen. Das oben angeführte Beispiel macht jedoch die Beziehung zwischen Kotlin und Java deutlich. Normalerweise würden Sie mit der kotlin-Laufzeitumgebung oder einem Build-Tool wie Gradle arbeiten. Dazu später mehr. First-Class-Funktionen in Kotlin Kotlin ist eine funktionale Sprache erster Klasse: Indem sie ermöglicht, Funktionsreferenzen aus anderen Funktionen zu übergeben oder zurückzugeben, bietet sie enorme Flexibilität. Oft ist es auch möglich, Java- und Kotlin-Code „zusammenzubringen“: // Main.kt fun main() { System.out.println("Hello from Java, InfoWorld!"); println("Hello, InfoWorld!") } Auf der anderen Seite gibt es jedoch einige Syntax-Unterschiede bei Kotlin, die dazu führen können, dass Java-Standards ungültig werden. Zum Beispiel erlaubt die Sprache keine primitiven Typen. In dieser Hinsicht ist Kotlin fast mehr Java als Java selbst: Hier ist wirklich alles ein Objekt – es gibt keine int-, long-, double– oder char-Ausnahmen (mit Project Valhalla bewegt sich Java in eine ganz ähnliche Richtung). Zudem unterscheidet Kotlin strikt zwischen veränderbaren und unveränderbaren Variablen – was einen allgemeinen Trend in modernen Programmiersprachen abbildet. Dabei stellt val eine unveränderbare, var eine veränderbare Variable dar: val myValInt: Int = 10; var myVarInt: Int = 10 // myValInt++; Aufmerksame Leser haben längst bemerkt, dass Semikolons in Kotlin wie in JavaScript optional sind. Generell ist es unter Kotlin-Devs üblich, auf abschließende Semikolons zu verzichten. Typen inferenziert Kotlin folgendermaßen: val myString = "FooBar"; println("My string ${myString} is a classic."); Dieses Code-Snippet demonstriert auch den in Kotlin integrierten Support für String-Interpolation, dessen Syntax der vieler Templating-Tools ähnelt. ${} kann dabei auch Expressions beinhalten (beispielsweise ${myString.upperCase()}). Enthält der Variablenname keine Sonderzeichen, können Sie auch auf eine vereinfachte Form zurückgreifen: println("When in doubt, $myString."); Unterfüttert wird das alles vom Typ-System von Java, auf das Sie folgendermaßen zugreifen: println(myString::class.java.typeName); // Outputs “String” Null-Handling mit Kotlin Die NullPointerException stellt eine der bekanntesten Ausnahmen in Java dar. Bei Kotlin sind Variablen standardmäßig nicht „nullbar“: Der Compiler verhindert es, normale Variablen auf null zu setzen. Sollten Sie darauf Wert legen, können Sie das folgendermaßen ändern: val myNullableString: String? = null Um mit Nullwerten umzugehen, verfügt Kotlin auch über den .?– und :?-Operator. Erstgenannter funktioniert ähnlich wie der optionale Chaining-Operator, um den JavaScript vor kurzem ergänzt wurde. Er ermöglicht einen „Short Circuit“ auf Nullwerte ohne ausführliche Überprüfungen: possiblyNull.?possiblyNullMember.?anotherMember Wenn einer der Teile null ist, gibt der gesamte Ausdruck null zurück, ohne einen Fehler aufzuwerfen. Mit dem Nullish Coalescing Operator :? ist es möglich, die linke Seite auf null zu testen und sie zurückgeben, wenn sie nicht null ist. Anderenfalls wird die rechte Seite zurückgegeben, die ebenfalls null sein kann: something :? somethingElse Wenn something null ist, erhalten Sie somethingElse. Collections in Kotlin Um mit Variablensammlungen zu arbeiten, verfügt Kotlin über Sets, Listen und Maps. Diese ermöglichen sowohl veränderbare als auch unveränderbare Varianten. Für eine veränderbare String-Liste würden Sie auf folgenden Befehl zurückgreifen: import kotlin.collections.*; fun main() { val books: MutableList = mutableListOf("Autobiography of a Yogi", "Slaughterhouse Five", "Phaedrus"); println(books[2]); } Wie Sie sehen, haben wir die Collections-Bibliothek importiert. Weil diese in der Kotlin-Standardbibliothek enthalten ist, können wir sie kompilieren: $ kotlinc Main.kt Dieser Versuch führt allerdings zu einem Fehler: $ java MainKt Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/collections/CollectionsKt at MainKt.main(Main.kt:14) at MainKt.main(Main.kt) Caused by: java.lang.ClassNotFoundException: kotlin.collections.CollectionsKt at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528) Hierbei handelt es sich um eine aus Java bekannte Fehlermeldung, die darüber Auskunft gibt, dass für CollectionsKt keine Klassendefinition vorhanden ist. Um das zu umgehen, binden Sie die Standard-Bibliothek folgendermaßen zur Laufzeit ein: $ java -cp /home/matthewcarltyson/kotlin:/home/matthewcarltyson/.sdkman/candidates/kotlin/current/lib/kotlin-stdlib.jar MainKt Phaedrus Dieser Befehl weist Java an, kotlin-stdlib.jar einzubinden. Eine andere Möglichkeit besteht darin, die Kotlin-Laufzeitumgebung zu nutzen, um stdlib automatisch einzubinden: $ kotlin MainKt Auf Listen greifen Sie wie auf Arrays zu – indem Sie Klammern verwenden: println(books[2]) // outputs “Phaedrus” Gradle mit Kotlin nutzen Die einfachste Möglichkeit, Gradle und Kotlin zusammen zu nutzen: Starten Sie ein neues Projekt mit gradle init. Dieser Befehl ruft einen interaktiven Fragebogen über die Kommandozeile auf: $ gradle init Select type of project to generate: 2: application Select implementation language: 4: Kotlin Split functionality across multiple subprojects?: 1: no - only one application project Select build script DSL: 2: Kotlin Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]: no Project name (default: kotlin): kotlin Source package (default: kotlin): com.infoworld Dieses simple Programm können Sie nun über das Stammverzeichnis des Projekts ausführen: $ ./gradlew run Anschließend erhalten Sie ein „Hello, World“. So ist das Projekt aufgebaut: /settings.gradle.kts - Global settings for Gradle /app/ build.gradle.kts - The build file /app/src/main/kotlin/com/infoworld/App.kt - The single source file Werfen wir nun einen Blick auf die App.kt-Datei: package com.infoworld class App { val greeting: String get() { return "Hello World!" } } fun main() { println(App().greeting) } In diesem Beispiel finden sich einige Features, die wir noch nicht behandelt haben. Darunter auch eine Package Declaration (die Package- und Verzeichnis-Struktur müssen in Kotlin nicht strikt übereinstimmen). Zudem sehen Sie hier die optimierte Kotlin-Syntax, um Klassen zu deklarieren. Per Default sind Klassen bei Kotlin öffentlich sichtbar – App ist also eine Public Class. Innerhalb dieser befindet sich ein read-only String-Member namens greeting. Dabei ist zu beachten, dass die greeting-Property eine get()-Funktion deklariert. Diese wird ausgeführt, wenn Sie den Dot-Operator nutzen, um darauf zuzugreifen. Im Folgenden versuchen wir uns an einem anspruchsvolleren Beispiel und laden die Charakter-Daten für Chewbacca über die Star-Wars-API herunter. Die App.kt-Datei lässt sich wie folgt ändern: //app/src/main/kotlin/com/infoworld/App.kt package com.infoworld import com.google.gson.Gson import java.net.URL class App { fun fetchAndPrintCharacterInfo(url: String) { val gson = Gson() val response = URL(url).readText() val character = gson.fromJson(response, StarWarsCharacter::class.java) println("Name: ${character.name}") println("Height: ${character.height}") } } data class StarWarsCharacter( val name: String, val height: String, ) fun main() { val chewbaccaUrl = "https://swapi.dev/api/people/13/" val app = App() app.fetchAndPrintCharacterInfo(chewbaccaUrl) } Dieses Snippet gewährt einen Einblick in Kotlins Data Class, die darauf konzipiert ist, Informationen zu speichern (ähnlich wie Value Objects in Java). Die StarWarsCharacter-Klasse verfügt über alle Standardmethoden wie Getter und Setter, hashCode, toString und equals. Das ist ideal, um die API-Daten in einen Container zu entpacken – was wir nun tun. Ergänzen Sie den dependencies-Abschnitt in /app/build.gradle.kts um folgende Abhängigkeiten: implementation("com.google.code.gson:gson:2.9.1") Das ermöglicht, die JSON-Daten von der API zu verarbeiten. Wenn Sie die Anwendung nun ausführen, sehen Sie einige Informationen über Chewbacca: $ ./gradlew run > Task :app:run Name: Chewbacca Height: 228 Hair color: null Eye color: null BUILD SUCCESSFUL in 2s (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!