Kotlin - Karl Szwillus - E-Book

Kotlin E-Book

Karl Szwillus

0,0
3,99 €

Beschreibung

  • Fundierte Einführung mit zahlreichen Beispielen aus der Praxis
  • Kotlin für Android- und Webanwendungen
  • Mit vielen Tipps für Java-Umsteiger

Kotlin ist eine Programmiersprache, die sich in den letzten Jahren von einem reinen Java-Ersatz für Android zu einer vollwertigen Cross-Plattform-Sprache entwickelt hat.

Dieses Buch richtet sich an Entwickler, die Kotlin als neue Programmiersprache kennenlernen und in einer Java-Umgebung wie Android einsetzen wollen, oder die sich für Multiplattform-Techniken interessieren. Dabei konzentriert sich der Autor auf die Grundlagen der Sprache und erläutert umfassend ihre Strukturen, Befehle und Sprachfeatures.

Anhand zahlreicher Beispiele lernen Sie, wie Sie Kotlin in einer Produktivumgebung effektiv einsetzen können. Da Kotlin funktionale Programmierung ermöglicht und sich an diesem Konzept orientiert, erläutert der Autor außerdem, was Sie wissen müssen, um funktionalen und objektorientierten Stil zu kombinieren.

Darüber hinaus erhalten Sie einen Ausblick auf weiterführende Themen und Konzepte wie automatische Tests, die Organisation von größeren Projekten durch Architekturmuster und die Nebenläufigkeit mit Kotlin-Coroutines.

Auch die Anwendung von Kotlin für Android wird vorgestellt und gezeigt, wie die neue Sprache konkret hilft, moderne Architekturen umzusetzen.

Zum Abschluss geht der Autor auf die Entwicklung von Cross-Plattform- sowie JavaScript-Anwendungen mit Kotlin ein.

Mit diesem Buch erhalten Sie einen umfassenden Einstieg in Kotlin. Es enthält viele Informationen für Entwickler, die sich das erste Mal mit einer statisch typisierten Sprache beschäftigen und für diejenigen, die von der Android-Entwicklung mit Java kommen und auf Kotlin umsteigen und bisherigen Code ergänzen oder ersetzen wollen.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 453

Bewertungen
0,0
0
0
0
0
0



Inhaltsverzeichnis
Impressum
Einleitung
Kapitel 1: Eigenschaften von Kotlin
1.1 Eine neue Sprache
1.2 Kotlin und Android
1.3 Vorteile von Kotlin
1.4 Ziele der Entwicklung von Kotlin
1.4.1 Übersichtlichkeit, präziser Ausdruck
1.4.2 Sicher‌heit
1.4.3 Interoperabi‌lität
Kapitel 2: Arbeiten mit Kotlin
2.1 Entwicklungsumgebung einrichten
2.1.1 IntelliJ
2.1.2 Android Studio‌
2.2 Tools‌
2.2.1 Kotlin-Compi‌ler
2.2.2 Kotlin-Compil‌er mit Gradle
2.2.3 Integrierte Entwicklungsumgebungen/IDE
2.2.4 Konvertierung von existierendem Code
Kapitel 3: Kotlin by example
3.1 Hello world!
3.2 Hello null!
3.2.1 Ein erster Test
3.2.2 Eine erste Exception
3.2.3 Eine erste Variable – Null-Sicherheit
3.2.4 ‌Let und La‌mbdas
3.2.5 Eine erste Schle‌ife
3.3 Hello Android!
3.4 Hello Kotlin!
Kapitel 4: Grundlagen und Daten
4.1 Expressions vs. Statements
4.2 Strukturierung von Code durch Dateien, Klassen, Funktionen und Blöcke
4.3 Funktionen
4.3.1 Direkte Funktionsauf‌rufe
4.3.2 Benutzung von Lambdas
4.4 Variablen
4.4.1 Deklaration: Immutable vs. Mutable, Zuweisung
4.4.2 Typen und Typsich‌erheit
4.4.3 Null-Siche‌rheit
4.4.4 Typinfe‌renz
4.4.5 Gene‌rics benutzen
4.4.6 B‌oxing
4.5 Besonderheiten der Datentypen
4.5.1 Za‌‌hlen
4.5.2 Boo‌‌lean
4.5.3 C‌‌hars und S‌‌trings – Zeichen und Zeichenketten
4.5.4 Obj‌ekte un‌d Any
4.5.5 Arr‌‌ays und Listen
4.5.6 Maps‌‌
4.5.7 Ra‌‌nges
Kapitel 5: Grundstrukturen
5.1 Kontrollstrukt‌uren
5.2 Verzweigu‌ngen mit if
5.3 Verzweigung mit whe‌n
5.4 Schleifen mit for und while
5.4.1 for-Schleifen
5.4.2 while-Schleifen
5.4.3 repeat
5.4.4 break/named break und continue
5.4.5 Funktionsbasierte Alternativen
5.5 Exception Handling mit try/c‌atch
5.6 Annotations
5.7 Datentypen‌
5.7.1 Type-Casting
5.7.2 Type-Casting und null
5.7.3 Smart Casts
5.7.4 Type Aliases
Kapitel 6: Funktionen und Lambdas
6.1 Funktionale Entwicklung
6.2 Syntax von Funktionen
6.2.1 Kurzformen von Funktionsdefinitionen
6.2.2 Parameter
6.2.3 Variable Anzahl von Parametern
6.2.4 Rückgabe
6.2.5 Destrukturierende Deklarationen
6.2.6 Kombination mehrerer Funktionsaufrufe
6.3 Höhere Funktion und Lambdas
6.3.1 Funktionen als Parameter
6.3.2 Funktionstyp für Variablen
6.4 Chaining von Lambdas
6.5 Rekursive Funktionen
6.6 Spezielle Funktionen
6.6.1 Lokale Funktionen
6.6.2 Inline-Funktionen
6.6.3 Infix-Funktionen
6.6.4 Actual-Funktionen
6.6.5 Überladene Operatoren
Kapitel 7: Packages, Klassen und Objekte
7.1 Architektur und Entwurf
7.2 Packages, Klassen und Interfaces
7.2.1 Klassen und Interfaces organisieren das Modell
7.2.2 Klassen und Interfaces, Vererbung
7.2.3 Packages organisieren das Projekt
7.2.4 Sichtbarkeitsmodifier
7.2.5 Import
7.3 Von der Klasse zum Objekt – Meet the members
7.3.1 Konstruktoren und Initializer
7.3.2 Propert‌ies
7.3.3 Custom Getter/Setter
7.3.4 Methoden
7.3.5 Innere Klassen
7.3.6 Companion Objects
7.4 Objekt-Anweisungen
7.4.1 Singletons via Objekt-Deklaration
7.4.2 Anonyme Klassen via Objekt-Ausdruck
7.4.3 Object-Statements bei Rückgaben
7.5 Datenklassen
7.6 Generics
7.6.1 Generische Klassen
7.6.2 Beschränkung der Typen: Invariant, Kovariant, Kontravariant
7.6.3 Generische Methoden
7.6.4 Reified parameters
7.7 Enum classes
7.8 Sealed classes
7.9 Extensions
7.10 Destrukturierende Deklarationen
Kapitel 8: Testing
8.1 Einführung
8.1.1 Unit-Tests
8.1.2 Integrationstests
8.1.3 Testsuite
8.1.4 Mocking und Dependency Injection
8.1.5 Konkret: Wie werden Tests geschrieben?
8.2 Erster JUnit‌-Test
8.3 Einrichten eines Testprojekts
8.4 Praxisbeispiel: Verkleinern von Funktionen
8.5 Das Testresultat lesen
8.6 Der Test von Hello world!
8.7 Test einer Klasse
8.8 Parametrisierte Tests
8.9 Testing Kotlin-Style
8.9.1 Testkomponenten
8.9.2 Spek
8.9.3 Kotlintest.io
8.9.4 kotlin.test: Unit-Tests in Multiplattform-Projekten
Kapitel 9: Kotlin für Fortgeschrittene
9.1 Alles zusammenbringen
9.2 Zielplattformen
9.3 Kotlin-Standard
9.3.1 run, let, apply, with, also
9.3.2 Takeif/Takeunless
9.3.3 Collections, Arrays und Listen
9.3.4 Operationen auf allen iterierbaren Elementen
9.3.5 Texttools
9.3.6 Reflection
9.4 Delegation
9.4.1 Property Delegation
9.4.2 Class Delegation
9.5 Service Location/Dependency Injection
9.5.1 Warum eigentlich?
9.5.2 Service Locator
9.5.3 Dependency Injection
9.6 Coroutines und Nebenläufigkeit
9.6.1 Launch und Scopes
9.6.2 Async, Await und Deferred
9.6.3 Producer, Consumer und Actor
9.7 Contracts
9.8 Idiomatischer Code
9.8.1 Unveränderliche/immutable Variablen
9.8.2 Kurzformen für null
9.8.3 Kurzschreibweisen für Funktionen
9.8.4 Nutzung von Class Properties
9.8.5 Chaining von nicht chainbaren Aufrufen
9.8.6 Extensions nutzen
9.8.7 DSL mit Lambdas
9.8.8 Infix-Notation für klare Sätze
Kapitel 10: Kotlin für Android
10.1 Android <3 Kotlin
10.2 Android-Komponenten
10.2.1 Package-Level und Überblick
10.2.2 Klassenlevel
10.3 Bestandteile des Android-Frameworks
10.3.1 Activities und Fragmente
10.3.2 Eine minimale App
10.3.3 Views, Rendering und Layouting
10.3.4 Der Lifecycle
10.3.5 Android Architecture Components
10.4 Architektur für größere App-Projekte
10.5 Das Architekturmodell MVP(I)
10.5.1 Der Vertrag
10.5.2 Initialisierung
10.5.3 Daten laden und initiale UI erstellen
10.5.4 Mehrere Presenter/Komponenten
10.5.5 Updates der UI und Reagieren auf Dateneingaben
10.6 Das Architekturmodell MVVM
10.6.1 MVVM-Komponenten anlegen
10.6.2 Initialisierung
10.6.3 Daten laden und initiale UI erstellen
10.6.4 Updates der UI und Reagieren auf Dateneingaben
10.7 MVP oder MVVM? It depends ...
10.8 Erweiterung von Android-Klassen
10.9 Android und Coroutines
10.10 Delegation für Android
10.10.1 Property Delegation
10.10.2 Klassendelegation
Kapitel 11: Zielplattformen für Kotlin
11.1 Multiplattform-Logik
11.2 Java
11.2.1 Java-Libraries
11.2.2 Reflection
11.2.3 Streams (Java 8)
11.2.4 Java Collections
11.2.5 Java Annotations
11.2.6 Annotation Use-Site Target
11.3 JavaScript in Kotlin
11.3.1 Einrichtung oder: Wie geht denn das?
11.3.2 Grundsätzliches zu Kotlin und JS
11.3.3 Standalone JS-App
11.4 JS-Standard-Bibliothek
11.4.1 Dynamic
11.4.2 Promises
11.4.3 Browser
11.4.4 JSON-Parsing
11.4.5 Nutzung von JS-Bibliotheken/-Aufrufen
11.5 Konvertierung von existierendem Java-Code zu JS
11.6 Konvertierung und Bearbeitung von existierendem JS-Code
11.7 Multiplattform-Projekte
11.7.1 Ein Multiplattform-Projekt beginnen
11.7.2 Expected/Actual
11.8 Native
Kapitel 12: Rück- und Ausblick
Anhang A: Referenztabellen
A.1 Factories
A.1.1 Factories für Arrays
A.1.2 Factories für Listen und Maps
A.2 Konvertierung von Listen/Arrays
A.3 Operationen auf allen iterierbaren Elementen
A.3.1 Zugriff auf einzelne Elemente
A.3.2 Zugriff auf Maps
A.3.3 Iteration über alle oder viele Elemente
A.3.4 Manipulation von Listen
A.3.5 Manipulation von Maps

Karl Szwillus

Kotlin

Einstieg und Praxis

Impressum

Bibliografische Information der Deutschen Nationalbibliothek Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über <http://dnb.d-nb.de> abrufbar.

ISBN 978-3-95845-855-0 1. Auflage 2020

www.mitp.de E-Mail: [email protected] Telefon: +49 7953 / 7189 - 079 Telefax: +49 7953 / 7189 - 082

© 2020 mitp Verlags GmbH & Co. KG

Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen.

Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften.

Lektorat: Sabine Schulz Sprachkorrektorat: Simone Fischer Coverbild: ©denyshutter – stock.adobe.comelectronic publication: III-satz, Husby, www.drei-satz.de

Dieses Ebook verwendet das ePub-Format und ist optimiert für die Nutzung mit dem iBooks-reader auf dem iPad von Apple. Bei der Verwendung anderer Reader kann es zu Darstellungsproblemen kommen.

Der Verlag räumt Ihnen mit dem Kauf des ebooks das Recht ein, die Inhalte im Rahmen des geltenden Urheberrechts zu nutzen. Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheherrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und Einspeicherung und Verarbeitung in elektronischen Systemen.

Der Verlag schützt seine ebooks vor Missbrauch des Urheberrechts durch ein digitales Rechtemanagement. Bei Kauf im Webshop des Verlages werden die ebooks mit einem nicht sichtbaren digitalen Wasserzeichen individuell pro Nutzer signiert.

Bei Kauf in anderen ebook-Webshops erfolgt die Signatur durch die Shopbetreiber. Angaben zu diesem DRM finden Sie auf den Seiten der jeweiligen Anbieter.

Einleitung

Fast jeder kennt das unangenehme Gefühl, einer wildfremden Person zuzuwinken, weil man kurz dachte, die freundliche Geste gälte einem selbst. Galt sie natürlich nicht, sondern der Person, die sich in direkter Linie hinter der eigenen Schulter im toten Winkel versteckte. Auf der Google I/O‌ 2017 habe ich erlebt, wie sich ein ganz ähnliches Empfinden einstellt, wenn man eine halbe Stunde lang in eine Fernsehkamera blickt, die in etwas mehr als Armeslänge vor einem positioniert ist. Selbstverständlich wusste ich, dass es keinen Grund gab, mich in dieser Weise zu portraitieren. Doch nach fünf Minuten ... und weiteren zehn ... es konnte doch nicht?

Konnte es natürlich nicht. Es ging um einen 17-jährigen High-School Studenten, den der Lebensweg seiner Eltern als Einwanderer aus Afghanistan und die in Amerika erlebte Hilfsbereitschaft inspiriert hat, selbst etwas zurückzugeben. In der Reihe vor mir. Sein Projekt verbesserte ohne teure Hardware die Aussagefähigkeit von Mammographien mithilfe von künstlicher Intelligenz. Die von ihm programmierten Routinen erkennen Muster in den Bildern und können so auch ohne medizinisches Fachpersonal präzisere Vorabdiagnosen zur Verfügung stellen.[1]

Eine knappe halbe Stunde zuvor gab es eine Ankündigung, die mir diesen Tag auch ohne die bemerkenswert große Kamera im Gedächtnis gehalten hätte: Die Ankündigung von Stephanie Saad Cuthbertson (Director Product Management Android zu der Zeit), Kotlin zu einer vollständig unterstützten Programmiersprache für Android zu erklären und mit dem Entwickler JetBrains‌ eine Gesellschaft zur Weiterentwicklung der Sprache zu gründen. Kotlin ist eine vergleichsweise junge Programmiersprache, deren erste stabile Version 2016 erschien. Seit 2011 wird sie von einem Team des Herstellers der Entwicklungsumgebung IntelliJ‌ weiterentwickelt und gepflegt. Hier besteht auch die offensichtliche Verbindung zu Java und Android, denn auch die von Google primär unterstützte IDE (Integrated Development Environment oder Entwicklungsumgebung) Android Studio basiert auf IntelliJ.

Dadurch war auch gewährleistet, dass es in Bezug auf die Tools keiner großen Umgewöhnung bedurfte. Und so haben sicherlich einige Android-Entwickler nach dieser Ankündigung 2017 ihre ersten Schritte in Kotlin mithilfe der automatischen Konvertierungsfunktion gemacht und schnell eines erkannt: Die neue Sprache löst sofort Probleme im bestehenden Code ihrer Anwendung:

Der Code wird kürzer und übersichtlicher

Der Code wird sicherer

Es ist kein Problem, Kotlin und Java miteinander in einem Projekt einzusetzen

Keine Semikolons‌(!)

Oder, um es mit den Worten von Google und Jetbrains zu sagen: Wichtige Merkmale von Kotlin sind: Es ist effektiv durch präzise Schreibweisen (concise‌), sicher (safe‌) und gut mit verschiedenen Umgebungen zu integrieren (interoperable‌).

Wie das in der Praxis aussieht und warum ich schon nach den ersten Arbeitstagen mit Kotlin kein Java mehr sehen mochte, versuche ich in diesem Buch zu erklären.

Ausrichtung des Buchs

Dieses Buch soll Entwicklern einen Einstieg in die Programmiersprache Kotlin ermöglichen. Es konzentriert sich auf die Grundlagen der Sprache und ihre Strukturen, Befehle und Sprachfeatures. Zusätzlich zur Erläuterung der ursprünglichen Aufgabe als ein verbesserter Java-Ersatz wird das aktuelle Haupteinsatzfeld Android behandelt und wie Kotlin die Android-Entwicklung verbessern – oder neutral: verändern – kann. Dabei werden aber Kenntnisse von Android vorausgesetzt, um den Fokus auf die Sprache Kotlin beizubehalten.

Das vorliegende Buch möchte dazu motivieren, vor einem Volleinstieg in Kotlin die Konvertierung Schritt für Schritt zu probieren. Das Stichwort lautet Interoperabilität. Auch in einem großen Java-Spring-Projekt können einzelne Features oder Klassen in Kotlin geschrieben oder in der Webanwendung einzelne Controller oder Datenklassen ergänzt werden. Bei den Beispielen benutze ich wenig Framework-Code und fokussiere mich auf die Umsetzung der Logik in Kotlin. Wenn, dann wird vor allem Android verwendet.

Generell ist es aber gut möglich, auch sein favorisiertes JavaScript- oder TypeScript-Framework weiterzunutzen. Je elaborierter die Build- und Deployment-Prozesse jedoch sind, desto weniger kann ich als App-Entwickler Details der Umsetzung beleuchten.

Darüber hinaus wagt das Kapitel 11 einen Ausflug in die Welt der Cross-Plattform-Entwicklung. Das ist wichtig für alle, deren Code in Zukunft aus einer Kotlin-Codebasis nicht nur auf Android-Smartphones oder im Browser laufen soll.

Zielgruppe

Dieses Buch ist für alle geschrieben, die sich für die Entwicklung mit Kotlin interessieren und die bereits grundsätzliche Kenntnisse in der Softwareentwicklung haben.

Dazu gehört zum Beispiel, dass Sie grundlegende Quelltext-Elemente wie Variablen, Konstanten, Kontrollstrukturen und Funktionen kennen und Ihnen Begriffe aus der objektorientierten Entwicklung wie Klasse, Objekt und Instanz geläufig sind. Programmierparadigmen und Muster der Softwareentwicklung werden ebenfalls nicht ausführlich erklärt, sondern vor allem dort erwähnt, wo es zum Verständnis der Unterschiede zwischen Kotlin und seinen Alternativen dient. Einblicke in die Programmiersprache Java helfen, sind aber nicht zwingend erforderlich.

Die meisten Entwickler sammeln ihre ersten Programmiererfahrungen in Kotlin nicht als Einsteiger in die Softwareentwicklung. Sie gehen mit Erwartungen aus bekannten Sprachen oder sogar mit existierendem Code an die Arbeit.

Mit Kotlin lässt sich in dieser Situation besonders gut arbeiten, denn es erfordert für viele Entwickler (Java, Android) keinen Umstieg auf eine andere Entwicklungsumgebung und verträgt sich mit bestehenden Infrastrukturen. Durch die hohe Flexibilität im Bereich der Interoperabilität ist es eine gute Strategie, in bestehendem Code einfach einmal einen konkreten Anwendungsfall zu ergänzen oder einzelne Klassen zu ersetzen. Damit können Entwicklungsteams eine informierte Entscheidung treffen, ohne zwangsläufig vor einem kompletten Neuanfang zu stehen.

Aufbau des Buchs

Der Aufbau dieses Buchs folgt meinen Erfahrungen als Hands-On-Entwickler und Geschäftsführer einer Agentur, in der Softwareentwickler verschiedener Erfahrungsstufen arbeiten.

In unserem Team haben alle Kotlin auf der Basis von Android kennengelernt. Sie waren und sind erfahrene Java-Entwickler und Experten in der Umsetzung von Apps. Wichtige Muster aus der App-Entwicklung und auch die Best Practices in Android waren also von vorneherein bekannt. Folgerichtig handelte es sich bei den ersten Experimenten denn auch eher um Java ohne Semikolons. Auf Basis einer fundierten Kenntnis der APIs und Tools für die Android-Entwicklung hat sich erst im Verlauf der Projekte ein tieferes Verständnis für die weitergehenden Möglichkeiten von Kotlin entwickelt. Das scheint mir typisch für eine Sprache, die entwickelt wurde, um den Unzulänglichkeiten einer existierenden Vorgängerin zu begegnen. Ich werde deshalb auf den folgenden Seiten ähnlich vorgehen.

In Kapitel 1 gebe ich zunächst einen Überblick über die Eigenschaften und Vorteile von Kotlin, seine Konzepten und die positiven Effekte auf die eigene Codebasis.

In Kapitel 2 erläutere ich kurz die zur Verfügung stehenden Tools, die ich für die ersten Schritte empfehle.

Kapitel 3 enthält kommentierte Beispiele, um zunächst ein Gefühl für die Sprache zu geben und ihre Möglichkeiten zu erkunden. Für diejenigen Leser, die bereits Vorkenntnisse in Android oder zum Beispiel Java haben, wird dieser Einstieg vielleicht für die ersten eigenen Versuche ausreichen. Einsteiger können dieses Kapitel auch erst mal überspringen. In den darauffolgenden Kapiteln folgt die systematische Betrachtung der einzelnen Sprachelemente.

Kapitel 4 stellt die grundlegende Syntax von Kotlin in den Mittelpunkt, und konzentriert sich auf die Grundstrukturen von Programmen und die Datentypen.

Tipp: Schnelleinstieg mit Kotlin KOANS

Wer direkt sehen möchte, wie Kotlin funktioniert, dem sei schon an dieser Stelle https://kotlinlang.org empfohlen. Unter dem Menüpunkt Learn finden sich dort die sogenannten Kotlin Koans – kleine Übungen, die direkt im Browser kompiliert und getestet werden. Darüber hinaus zeigen sie auch, wie man von Anfang an mit Tests sinnvolle Validierungen der eigenen Überlegungen durchführen kann. Insofern ein Must-Read (and try) für den angehenden Kotlin-Entwickler.

Auch die Beispiele aus dem Buch können aus dem GitHub-Repository dorthin kopiert, ausprobiert und variiert werden.

In Kapitel 5 werden die Kontrollstrukturen vorgestellt. Es geht also um Verzweigen und Wiederholen – und weitere daran angelehnte Sprachfeatures.

Das Kapitel 6 widmet sich den Funktionen und ihren verschiedenen Sonderformen. Ich werde dort eine längere Zeit mit höheren Funktionen und Lambdas verbringen, aber auch die Grundlagen von Funktionen ausführlich erklären.

Darauf folgt in Kapitel 7 ein ausführlicher Block zu den objektorientierten Anteilen von Kotlin. Hier geht es um alle Besonderheiten von Klassen, Objekten und Funktionen im Zusammenspiel. Dafür wird neben einzelnen Code-Schnipseln ein erstes Projekt vorgestellt.

Dieses Projekt beinhaltet eine Expression-Bibliothek, die in der Lage ist, mathematische Ausdrücke zu interpretieren und auszurechnen. Bislang liegt dieser Open-Source-Code in Objective-C, Swift und Java vor, in diesem Kapitel entsteht eine Kotlin-Version sowie eine Kommandozeilen-Anwendung, die sie nutzbar macht.

Kapitel 8 ist dem Thema automatische Tests in Kotlin gewidmet. Für die Nutzung der Test-Frameworks werden die Inhalte der vorherigen Kapitel als Handwerkszeug benötigt. Die Tests selbst beziehen sich vor allem auf das Testen von Funktionen und Klassen.

Kapitel 9 steigt tiefer in die komplexeren Konzepte von Kotlin ein, die auf dieser Basis aufbauen. Thema ist hier die Organisation von größeren Projekten durch Architekturmuster. Die Nebenläufigkeit mit Kotlin-Coroutines nimmt einen guten Teil des Kapitels ein und last but not least bespreche ich die Veränderungen im Denken und im Code, die sich aus der Kombination von funktionalem und objektorientiertem Stil ergeben.

Kapitel 10 ist Android gewidmet – hier entsteht eine vollständige App in Kotlin. Auch wenn das Kapitel mit den Grundlagen beginnt, ist es hier nicht möglich, alle Aspekte und Bibliotheken von Android zu behandeln. Der Schwerpunkt liegt auf moderner Architektur und den Anteilen, die sich durch Kotlin besser umsetzen lassen.

Kotlin ist seit der Version 1.2 in Bezug auf Interoperabilität einen Schritt weitergekommen und bietet auch Optionen zum Kompilieren in JavaScript und nativen iOS-Code. Dazu mehr in Kapitel 11.

Downloads zum Buch

Im Repository https://github.com/kotlin-karlszwillus‌ finden sich Android-Beispiele, die Kotlin-Portierung der Expression-Bibliothek und die Listings aus den anderen Kapiteln zum Ausprobieren, mit Sourcecode-Dokumentation.

Wer mit GitHub nicht vertraut ist, kann den Großteil der Inhalte auch über die Website des Verlags herunterladen: www.mitp.de/853

Über die Projekte in diesem Buch

Es gibt im Buch kein durchgehendes Projekt, mit dem alle verschiedenen Bereiche von Kotlin gestreift werden. Vielmehr habe ich aus der Praxis verschiedene Versatzstücke aus Projekten herausgelöst, die einzelne Schritte und Techniken der jeweiligen Kapitel illustrieren. So können Sie sich auch einzelne Themen im Buch ansehen, ohne sich in ein großes Beispielprojekt eindenken zu müssen.

Am Anfang des Buchs stehen noch die einzelnen Anweisungen und Ausdrücke im Mittelpunkt, hier handelt es sich um einfach gewählte Beispiele.

Damit ich in der Lage bin, auch komplexere Aufgaben zu zeigen, benutze ich eine Open-Source-Bibliothek, die ich einmal von der Kommandozeile und später auch in einer App verwende. Sie stellt eine vollwertige Sprache zum Lösen von Ausdrücken innerhalb von Formularen oder anderen Anwendungen zur Verfügung. Ihr Name ist NRExpressionLib, sie stammt vom iOS-Entwickler Nikolai Ruhe aus Berlin – wir haben in mehreren Projekten zusammengearbeitet. Da unsere Firma sie bereits von Swift nach Java portiert hat, gehe ich nun einen Schritt weiter und konvertiere sie in die Sprache Kotlin. Diese Aufgabe ist kein klassischer Einstiegspunkt, doch die Konvertierung, auch mithilfe der automatischen Konvertierungsfunktion, führte auch mich zu einigen interessanten Herausforderungen, an denen sich zum Beispiel die Inkompatibilitäten zwischen der Handhabung von Generics und den strengen Regeln für Typen bei Kotlin zeigen lassen.

Ein zweites Projekt stammt aus der Praxis und bildet eine Bibliothek von Meditationsübungen ab. Aufgaben wie Navigation und die Darstellung von Listen kann ich anhand dieser Listings einfacher demonstrieren. Diese App steht nicht als vollständiges Codebeispiel zur Verfügung, sondern lediglich in Auszügen, bzw. einzelnen Komponenten, die ausprobiert werden können. Sie ist aber im Play Store als »Key Meditation« kostenlos verfügbar.

Nicht alle Listings im Buch stammen aus diesen beiden Projekten. Einige stehen einfach für sich oder kommen in leicht abgewandelter Form aus dem Arbeitsalltag eines App-Entwicklers.

Die Codebeispiele im Buch sind daher Auszüge aus längeren Listings, die auf der Seite des Verlags unter www.mitp.de/853‌ und im öffentlichen Repository unter https://github.com/kotlin-karlszwillus zur Verfügung stehen.

Auf eine vollständige Befehlsreferenz habe ich zugunsten der bekannten Online-Quellen verzichtet, der Anhang A enthält aber kürzere Übersichten zu den Standardpackages, die sich auch plattformübergreifend verwenden lassen.

Eine Mischung von Deutsch und Englisch lässt sich nicht ganz vermeiden. Bei Fachbegriffen gebe ich den englischen Versionen den Vorzug und verwende eingedeutschte oder übersetzte Bezeichner nur dort, wo sie vergleichbar allgemeingültig sind.

Was nicht in diesem Buch steht

Jeder Autor entscheidet über Schwerpunkte und Inhalte eines Buchs, doch für den einen oder anderen mag es wichtiger sein, welche Themen nicht behandelt werden. Für mich sind dies in aller Kürze: keine RX-basierte Entwicklung, so gut wie keine experimentellen Features (mit Ausnahmen bei Coroutines und Contracts), kein Kotlin/Native und nur wenig über Multiplattform-Projekte.

Kotlin ist eine Sprache, deren Entwicklung noch in vollem Gang ist. Dabei werden vor allem auch im Bereich der Interoperabilität immer wieder neue Welten erschlossen. Mit der Version 1.2 ist Kotlin/Native dazugekommen, ein Setup für die Anbindung verschiedener Umgebungen, die auf C und moderneren Ableitungen davon basieren. Damit ist theoretisch ein Einstieg in die Entwicklung von iOS- und Desktop-Varianten möglich. Hierfür sind zum jetzigen Zeitpunkt noch sehr viel Wissen und Basteltalent in den ursprünglichen Sprachen notwendig, das mir fehlt. Ich freue mich aber auf weiteren Fortschritt in diesem Bereich.

Das zweite Thema, das lediglich gestreift wird, sind Multiplattform-Projekte. Tatsächlich ist ein Projekt in einem solchen Szenario umgesetzt, doch die Unterstützung ist auch in der Version 1.3 noch als experimentell gekennzeichnet. Aus diesem Grund habe ich mich entschieden, auch diesen Teil nur anzureißen und für eine spätere Ergänzung aufzuheben.

Zuletzt habe ich persönlich keine starke Zuneigung zur reaktiven Programmierung mit RxJava oder RxKotlin, auch wenn sie ihre Vorteile hat und auch regelmäßig Teil von datenintensiven Projekten ist. In der vorliegenden Ausgabe war mir der Fokus auf den Kotlin-eigenen Mechanismen im Bereich Coroutines, Observer und Mapping wichtiger. Für Android habe ich die Vorstellung von LiveData und ViewModel vorgezogen, die in dem gleichen Bereich im Einsatz sind, der heute häufig von Rx-Komponenten abgedeckt wird.

Weiterentwicklung von Kotlin

Ein wichtiges Anliegen habe ich in Bezug auf Aktualität und Updates der Sprache: Selbstverständlich werden sich von der Erstellung dieses Manuskripts bis zur Veröffentlichung Dinge ändern.

Insbesondere im Bereich von Bibliotheken verändern sich Möglichkeiten und APIs schnell und häufig. Zwar habe ich darauf geachtet, welche Veränderungen zur Erstellung des Manuskripts bereits absehbar waren, doch bereits mit dem nächsten größeren Update können sich auch grundlegende Mechanismen ändern.

Als Beispiel seien hier die Coroutines genannt, die mit der Version 1.2 eingeführt wurden und ein Ersatz für Java-basiertes Multithreading sind. Daher möchte dieses Buch vor allem die Grundlagen vermitteln, mit denen Sie funktionierenden, gut strukturierten und durchdachten Kotlin-Code erstellen können.

Über den Autor

Meine eigene Ausbildung nennt sich Medienwirt – ein Diplomstudium, das mir weitreichende Freiheiten und Interpretationsmöglichkeiten gewährt hat. So konnte ich die Programmierung, bis dahin Hobby und Schulfach, auch an der Universität weiterverfolgen, dann unter dem Stichwort »Neue Medien«. Heute arbeite ich als Geschäftsführer der Agentur Karlmax Berlin an verschiedenen Kundenprojekten im Bereich Apps.

Meine tägliche Arbeit hat bis vor Kurzem auch noch stark in den Projekten stattgefunden, sodass ich auch mit Kotlin dort meinen ersten Kontaktpunkte hatte.

Unsere Agentur hatte das Glück, dass wir mit zwei Kunden zum Zeitpunkt der Bekanntgabe von Kotlin als offizieller Entwicklungssprache für Android bereits über ein Jahr an Projekten mit Kotlin arbeiten durften. Die positiven Einflüsse auf eine Android-App kannten wir so bereits durch konkrete Projekte. Nicht zuletzt mit dieser Erfahrung im Rücken möchte ich alle Entwickler aus dem Java- und Android-Umfeld einladen, sich mit Kotlin zu beschäftigen.

[1] Im Video der Keynote bei 1:50:50 können sich die Leserinnen und Leser dieses Buchs ein Bild von mir im Jahr 2017 machen. Ganz Kamera-Unprofi erkennt man auch den Moment, in dem ich begriffen habe, dass es ganz sicher nicht um mich geht.

Kapitel 1: Eigenschaften von Kotlin

When I visited Jetbrains for the first time in Spring 2010, I came fairly certain that the world didn't need another general-purpose programming language.

– Andrey Breslav

1.1  Eine neue Sprache

Braucht es noch eine neue Programmiersprache auf JVM-Basis? Diese Frage stellt Andrey Breslav in der Einleitung von Kotlin in Action, wenn er seine Entscheidung begründet, nach dem Kennenlernen des Projekts Kotlin im Jahr 2010 als Chefentwickler und Architekt in das Projekt einzusteigen. Wären Sie auch dieser Meinung, dann würden Sie dieses Buch jetzt wahrscheinlich nicht in der Hand halten. Was meine Gedanken zu dieser Aussage sind, soll auch Sie noch einmal darin bestärken, dass die Entscheidung für Kotlin eine kluge ist:

Java‌ ist eine populäre Sprache in der Lehre und hat auch seine Nischen in Server- und Mobileanwendungen gefunden. Doch seit Jahren existieren bereits vielfältige Ansätze, die inhärenten Probleme der Sprache zu umgehen oder Sprachelemente zu modernisieren. Aufgrund der auch durch Rechtsstreitigkeiten zwischenzeitlich verlangsamten Java-Entwicklung‌ fanden diese jedoch wenig Berücksichtigung im Sprachstandard. Umgebungen wie Android sind aus verschiedenen Gründen zur Kompatibilität mit alten Versionen verdammt.

Aus diesen Gründen hat sich die Sprachentwicklung in Derivate‌ und auf Java-Technologie basierende Komponenten verlagert. Bekannte Beispiele für diesen Sprachansatz sind Scala, Clojure oder Groovy. Dazu kommen zwei gute Dutzend weitere Varianten, die sich entweder in bestimmten Branchen durchgesetzt haben oder zur Lösung spezieller Aufgaben im Scripting oder als Definitionssprachen dienen. Und seit einigen Jahren tummelt sich auch Kotlin in dieser illustren Menge.

Bei der ersten Präsentation ihrer neuen Sprache nannten die Entwickler von JetBrains Scala als ihre Referenz. Scala‌ ist zwar mit den richtigen Sprachfeatures ausgestattet, aber mit einem zu langsamen Compiler geschlagen. Darüber hinaus gilt Scala nicht unbedingt als einsteigerfreundlich; es handelt sich im Gegenteil um eine der Sprachen, die Einsteigern nie suggeriert, mehr verstanden zu haben als sie selbst glauben.

Als langjähriger Entwickler von IDEs für Java hatte das JetBrains-Team eine klare Vorstellung von den Problemen existierender Java-Software auf der einen und den Wünschen der Entwickler auf der anderen Seite. Insofern stellt Kotlin aus der Perspektive seiner Erfinder auch eine Möglichkeit dar, Entwickler an ihre Tools zu binden und ihnen neben der Entwicklungsumgebung auch auf der Sprachebene einen voll kompatiblen Ersatz zu bieten. Interoperabilität‌‌ mit 100% Java-Kompatibilität war das Ziel.

Wenige Jahre später folgten erste Komponenten für die Arbeit mit Android, und spätestens seit der Zusammenarbeit von Google und JetBrains in der Etablierung von Android Studio als Standard-IDE für die Entwicklung von Apps schien die erfolgversprechendste Nische von Kotlin besetzt.

Das Versprechen der Interoperabilität beschränkt sich nicht auf Komponenten innerhalb von Java oder anderen Java-basierten Frameworks. Konsequent wird auch die Kompilierung auf andere Plattformen‌ vorangetrieben, wie zum Beispiel in Desktop-Anwendungen, JavaScript oder auch natives iOS.

Neben den Gemeinsamkeiten gilt es jedoch auch, mit Kotlin‌ neue Konzepte zu verstehen und den Stil der entstehenden Software anzupassen. Drei wesentliche Spracheigenschaften sollten Entwickler im Kopf haben, wenn sie sich an die Arbeit mit Kotlin machen:

Kotlin ist objektorientiert und funktional.

Es verwendet und verlangt statische Typen.

Im Gegensatz zu Java ist Kotlin Null-Safe.

Java wurde lange Zeit objektorientiert und imperativ benutzt und gelehrt – zumindest bis zur Version 8, die erste Aspekte funktionaler Programmierung eingeführt hat. Im Gegensatz dazu ist der beherrschende Stil von Kotlin die funktionale Programmierung. Dazu gehört, Programmcode in Funktionen‌ zu differenzieren und unveränderliche Datenstrukturen zu bevorzugen. In der Koordination von Lese- und Schreibzugriffen und dem Management von Abhängigkeiten im Quellcode liegen in der Praxis immer wieder Probleme der imperativen und auch der objektorientierten Programmierung.

Die größten davon sind unerwünschte Seiteneffekte und implizite Abhängigkeiten zwischen Methodenaufrufen und Objektzuständen.

In der Objektorientierung ist es gute Praxis, ein Objekt möglichst vollständig nachzubilden und die zentralen Eigenschaften oder Attribute mit den Aktivitäten oder Methoden zu gruppieren, die den Zugang zu den Daten schaffen. In dieser Logik ist die Klasse der statische Rahmen aller Objekte des gleichen Typs. Sie stellt sicher, dass alle Instanzen die dort bestimmten Eigenschaften erfüllen und Daten bereitstellen. All diese Mechanismen unterstützt Kotlin und verbessert sie im gleichen Schritt.

1.2  Kotlin und Android

Hier kann man guten Gewissens sagen, dass Android zu dem Zeitpunkt, als die Entscheidung fiel, Kotlin als möglichen Ersatz in ersten Demos zu präsentieren, ein besonders dankbarer Kandidat für weitreichende Verbesserungen war.

Das lässt sich gut am Beispiel der Android Activity‌ nachvollziehen. Diese Klasse ist ein sehr komplexes Stück Code, sie modelliert die Repräsentation eines »Screens« auf dem Smartphone und stellt den zentralen Anbindungspunkt für das Verhalten einer App dar. Es handelt sich um eine Klasse von 8.000 Zeilen mit etwa 40 Attributen, hinter denen zum Teil wieder komplexe Strukturen stecken. Teilweise setzen sie auch Nebenläufigkeit voraus oder werden durch das System regelmäßig ausgewertet oder beschrieben.

Und auch, wenn diese Klasse selbst in den Apps lediglich benutzt wurde, so schaffte sie mit ihren umfangreichen Schnittstellen die Grundlage für toxische Entwicklungsmuster.

In den ersten Versionen von Android gab es darüber hinaus wenig Vorgaben, nach welchen Mustern der Quellcode einer App zu strukturieren ist. Der übliche Aufbau begann mit der Initialisierung der App-Zustände in der Methode publicvoidonCreate(BundlesavedInstanceState) in einer von Activity abgeleiteten Klasse. Diese Methode, vom Android-System aufgerufen, war und ist der kanonische Startpunkt einer App. Auch die Handhabung weiterer Komponenten folgte dann in dieser Klasse, herausgezogen lediglich die Views und ihre Backing Objects wie Adapter und Datenbanken.

Die gesamte Komplexität‌‌ hing damit von Anfang an in jeder einzelnen Komponente einer App, die auf dieser Basis entwickelt wurde. Aufgrund der Funktionsfülle hatten auch die abgeleiteten Klassen eine Tendenz zu unkontrolliertem und schlecht kontrollierbarem Wachstum. Da nehme ich mich persönlich gar nicht aus.

Um nun eine einzelne Methode dieser Klasse sinnvoll per Unit-Test validieren zu können, bedurfte es nicht nur einer Instanz der entsprechenden Activity, sondern mindestens noch eines Aufrufs der Methode onCreate(). Im Normalfall benötigte dieser Aufruf eine komplette Systemumgebung (vulgo Smartphone oder Simulator), da diese Methode in der Vererbungshierarchie auf verschiedene Komponenten zugreift, die im Normalfall auf einem eingeschalteten Smartphone zur Verfügung stehen. In einem Unit-Test, dem kein Android-Gerät zur Verfügung steht, zog dies entweder aufwändiges Mocking von Komponenten nach sich – oder den Verzicht auf Unit-Tests.

Das Ergebnis waren zahlreiche ungetestete bis schlecht getestete Apps und damit eine deutlich gefühlte Unterlegenheit gegenüber Umgebungen[1], in denen die gute Testbarkeit des Codes eine lange geübte Selbstverständlichkeit darstellte.

Zunächst sind an dieser Stelle Anbieter von bekannten Apps eingesprungen, die durch das Sponsoring von Open-Source-Entwicklungen für Abhilfe gesorgt haben. Sie führten Techniken und Strukturen wie die Architekturmodelle‌MVP und MVVM für Android ein und vereinfachten die Organisation von Abhängigkeiten mit Dependency Injection oder auch konkrete Aufgaben wie Bilderhandling und Netzwerk-Kommunikation. Mit den entsprechenden Libraries von Square, Facebook und anderen hat wohl jeder Android-Entwickler mehr als einen kurzen Flirt verbracht. Immerhin sorgten sie für strukturierteren Code.

Google verbesserte Android jedoch in den letzten Jahren durch neue Architekturansätze und leichtere Komponenten auf dieser Seite stark und machte viele der oben genannten Komponenten zu Teilen des Frameworks. Das ist aber nur eine Seite der Medaille.

Denn der Code, der auf diesen komplexen Bestandteilen aufsetzt, soll sich auf seine eigenen Qualitäten und Aufgaben fokussieren. Wenn das mobile Betriebssystem schon so große Teile der Aufgaben abnimmt, dann kann der eigene Code möglichst reduziert und möglichst präzise sein. In der Zwischenzeit hat sich der Blick dafür auf das Paradigma der funktionalen Entwicklung gerichtet.

1.3  Vorteile von Kotlin

Auf ganz grundsätzliche Art können die Sprachkonstrukte aus der funktionalen Entwicklung die Testbarkeit erleichtern oder sogar forcieren. Und diese Aspekte führt Kotlin‌ als grundlegenden Bestandteil seiner DNA mit sich.

Eine »reine«‌ (pure function) Funktion, die von außen alle nötigen Daten zur Bearbeitung als Parameter erhält und dann ein Ergebnis zurückgibt, ohne Daten an anderer Stelle zu manipulieren, kann leicht getestet werden. Je mehr Querbeziehungen zu anderen Daten oder Objekten bestehen oder wenn komplexere Systemzustände in die Ausführung der Funktion hineinspielen, desto schwieriger wird es, den einen Fall zu isolieren. Wenn sich aber der eigene Code darauf verlassen kann, dass die standardisierten Bibliotheken gut getestet und vollständig sind, dann lohnt es sich, auch den eigenen Use-Case möglichst präzise aufzuschreiben.

Die Arbeit mit kurzen Funktionen, unveränderlichen Datenstrukturen und höheren Funktionen‌ führt dazu, dass die eigenen Code-Bestandteile nicht nur kürzer, sondern auch besser testbar werden.

Statische Typisierung‌ und Null-Sicherheit‌ stehen ebenfalls auf der Seite des Forcierens von besserer Wartbarkeit, weil sie Entwicklern die Mittel für den laxen Umgang mit seinen Variablen nehmen. Gerade bei einem komplexen System wie dem Smartphone lag und liegt auch hier großes Potenzial zur Verbesserung.

Wenn die oben vorgestellten Techniken aus der funktionalen Entwicklung und bessere Tests vor allem zur Entwicklungs- und Compilezeit wirken, so bedeuten statische Typen und Null-Sicherheit vor allem bessere Sicherheit‌ zur Laufzeit. Sie bringen Klarheit über den Zustand einer Variable im Verlauf ihrer Benutzung, auch wenn der Code im Einsatz ist. Das gilt umso mehr, wenn der Umstieg von einer dynamisch typisierten Sprache wie JavaScript passiert.

Das jedoch funktioniert‌ nur dann gut, wenn vorhersagbar ist, welchen Wert eine Variable zu einem Zeitpunkt annehmen kann. Veränderliche Datenstrukturen bedeuten bei jeder Zuweisung Verantwortung des Entwicklers für die Zulässigkeit der Operation. In einem System mit unveränderlichen Strukturen kann diese Verantwortung an den Compiler übertragen werden.

Eine Funktion, deren Rückgabewert durch einen Test validiert wird und deren Ergebnis in eine neue Variable geschrieben wird, bedeutet eine testbare Kette von Operationen.

Davon können auch Apps profitieren, denn sämtlicher Quellcode, der auf das Framework Android aufbaut, liegt im Zuständigkeitsbereich des Entwicklers. Eine gute objektorientierte Modellierung, die konsequent Vererbung und Delegation nutzt und intern möglichst auf unveränderliche Datenstrukturen und einzelne Funktionen setzt, kann als aktueller Goldstandard in der App-Entwicklung gelten.

[1] Damit sind auch andere JAVA-basierte Umgebungen gemeint.

[2] Keith Bostic über Perl: »Perl – The only language that looks the same before and after RSA encryption.« Nur als eine Reminiszenz für die, die sich erinnern.

Kapitel 2: Arbeiten mit Kotlin

2.1  Entwicklungsumgebung einrichten

Um die ersten Schritte mit den Beispielen der kommenden Kapitel ausführen zu können, ist jetzt der Zeitpunkt, eine entsprechende Umgebung zu konfigurieren, um Kotlin auszuprobieren. Meine Empfehlung ist es, hierzu auf eine der frei verfügbaren Entwicklungsumgebungen zu setzen.

Da die ersten Schritte in einem neuen Tool eventuell nicht ganz selbsterklärend sind, stelle ich die beiden wichtigsten Umgebungen vor und zeige sie bis zum ersten minimalen funktionierenden Beispiel. Nun ändern sich Softwareversionen in der Regel schneller als Bücher, doch die grundlegenden Fragen der Organisation haben höchstwahrscheinlich noch eine Weile Bestand, auch wenn die Screens sich bis zur Drucklegung eventuell in Details schon wieder geändert haben.

Es besteht die Wahl zwischen zwei Varianten:

IntelliJ‌ Community Edition: Für alle, deren Fokus nicht direkt auf Android liegt, oder die eventuell auch komplexere Cross-Plattform-Projekte ausprobieren möchten

Android Studio‌‌: Für diejenigen, deren Projekte auf Android beschränkt sind

2.1.1  IntelliJ

Nach der Auswahl Projekt > Neu stehen verschiedene Optionen für Kotlin-Projekte‌ zur Verfügung.

Abb. 2.1: Projektassistent von IntelliJ

Für die Beispielprojekte in den ersten Kapiteln reicht in der Regel das einfache Kotlin(Java)-Projekt aus. In den späteren Kapiteln wird dann auch die Variante für JavaScript, beziehungsweise ein Cross-Plattform-Projekt, verwendet. Wie an den Bezeichnern bereits ersichtlich ist, handelt es sich zum Teil um experimentelle Features. Diese sind nutzbar, es ist jedoch nicht garantiert, dass nach einem Update der Sprache oder der Tools alles noch läuft wie zuvor.

Im nächsten Schritt muss das Kind ‌einen Namen bekommen. Wer Maven (ein anderes Tool zur Buildorganisation, vergleichbar mit Gradle) nutzt, wird die Einteilung in Artifact-ID, Group-ID und Version kennen. Die Group-ID kann leer bleiben, die Artifact-ID sollte den Projektnamen erhalten, und die Version kann auch zunächst auf dem Default-Wert stehen bleiben.

Abb. 2.2: Projektdetails

Die Projekte in IntelliJ werden standardmäßig mit Gradle konfiguriert und gebaut. Daher ist dieser Schritt wichtig. Im Normalfall sollte hier der Gradle-Wrapper aus der Basisinstallation gute Dienste tun.

Es kann im Einzelfall vorkommen, dass sich der aktuelle Wrapper nicht mit der Version von Plug-ins oder auch Java verträgt‌‌‌, in diesem Fall kann Gradle auch manuell installiert werden. Sollte das Tool Update-Bedarf anmelden, empfiehlt es sich in der Regel, diesem Rat zu folgen.

Tipp: Update Gradle-Wrapper

Falls sich Fehlermeldungen beim Erstellen des ersten Projekts zeigen, die anzeigen, dass Komponenten nicht gefunden werden oder der Gradle Sync nicht erfolgreich durchgeführt wird, empfiehlt sich ein Check der Version(en) von Java, IntelliJ, Kotlin-Plug-in für IntelliJ und Gradle-Wrapper. Sollte dieser nicht aktuell sein, ist ein Update möglich:

./gradlew wrapper --gradle-version 4.8.1 (aktuelle Version)

Mehr Informationen zu Gradle und Stand-Alone-Downloads gibt es unter folgender Adresse:

https://gradle.org/

Abb. 2.3: Positives Feedback vom gradle in einem leeren Projekt

Mit diesem leeren Projekt‌ kann es im Prinzip losgehen.

Als Nächstes müssen noch grundlegende Verzeichnisse angelegt werden (oder die Option Neue Module mit leerem Source-Verzeichnis anlegen und in den Settings anhaken.)

Die Ordnerstruktur sollte folgenden Aufbau haben: src/main/kotlin.

Nun ist es an der Zeit, darin die erste Datei anzulegen. Passend zum Projekt soll sie den Namen firstrun.kt tragen. Diese Datei benötigt ein wenig »overhead«, damit die Ausführung leicht möglich ist. Die Anweisungen machen die Kotlin-Anwendung kompatibel zur JVM. Das Ergebnis dieser Schritte sollte dann so aussehen:

Abb. 2.4: Projektbildschirm mit Struktur (links), Code (rechts) und Build-Fenster (unten)

Der letzte Schritt ist dann, eine Run-Configuration‌zu erstellen, damit der Play-Button zum Ausprobieren des Codes glühen kann.

Dazu wählen Sie in dem leeren Dropdown-Menü neben dem ausgegrauten Play-Button (vorheriger Screen rechts oben) den Punkt Edit configurations ... oder Konfigurationen bearbeiten .... Dort folgt mit dem Klick auf das Plus das Auswahlmenü für die Konfigurationstypen.

Hier wählen Sie Kotlin aus, um die grundlegenden Einstellungen für das erste Projekt zu öffnen (s. Abbildung 2.5)

Bei diesem letzten Schritt müssen Sie einmal die gerade erzeugte Klasse in dem hervorgehobenen Bereich Use classpath of Submodule auswählen.

Abb. 2.5: Build-Konfigurationen

Abb. 2.6: Build-Konfigurationsdetails

Im folgenden Kapitel folgt Inhalt, mit dem die main-Methode gefüllt und ausprobiert werden kann.

2.1.2  Android Studio‌

Mit dem Projektassistenten legen Sie auch in Android Studio‌‌ eine leere Applikation an. Dieser Schritt generiert bereits ersten Kotlin-Code und ein leeres Layout, in dem Sie direkt arbeiten können und das auf dem Simulator oder dem eigenen Handy einen App Screen erzeugen sollte.

Abb. 2.7: Projektassistent Android Studio

Im ersten Schritt scheint das Template‌‌Empty Activity zu passen, da es eine funktionierende Grundlage schafft, ohne viel Android-Infrastruktur zu erstellen, die in den ersten Schritten nicht notwendig ist. Wer sich mit Android auskennt, kann selbstverständlich auch mit einer Android TV App oder einer Fragment ViewModel-Variante beginnen.

Abb. 2.8: Projektdetails konfigurieren

Im nächsten Schritt legen Sie die Details fest, eventuell fällt hier auch erneute Downloadzeit für die richtige Android-Version an. Im Beispiel habe ich mich für eine recht alte API-Level entschieden, in einem Testprojekt kann das gerne aktueller sein. Der Name der App kann frei gewählt werden, der Package-Name muss den Konventionen für Java-Packages folgen und darf nur Kleinbuchstaben ohne Sonderzeichen enthalten.

Das Resultat ist eine Minimalapp im Code, die auch direkt zum Ausführen konfiguriert ist.

Die ersten Beispiele in diesem Buch gehen davon aus, dass der Code auf der Konsole ausgeführt wird. Es ist aber kein Problem, die Beispiele leicht anzupassen und sie dann entweder aus der Konsole von Android zu sehen oder aber in einem TextView und damit auch direkt in einer App auszugeben.

Abb. 2.9: Hauptfenster Android Studio mit Projektdaten

Hinweis: Nutzung mit einem Android-Projekt

Um die einfache Konsolenausgabe zu erreichen, die in den Codebeispielen mit print("Irgendwas") gemacht wird, kann in einer Android-App System.out.print("Irgendwas") verwendet werden – bzw. die Variante mit println.

Um Ausgaben mit dem Textview in einer App zu machen, muss dieser einmal in der Applikation aus der Layout-Datei gelesen werden (oder mittels kotlin-android-extensions direkt importiert) und kann dann mit textView.text"Irgendwas" genutzt werden, um die Ausgabe zu machen.

Führt man die App einmal aus und lässt sie sich anzeigen, so grüßen die Worte »Hello world« in einem ansonsten leeren App-Screen mit dem Titel Kotlin App.

2.2  Tools‌

Kotlin als Programmiersprache ist einigermaßen Tool-agnostisch. Sie können in einem beliebigen Text-Editor entwickeln. Größeren Komfort und sinnvolle Unterstützung bietet jedoch die integrierte Entwicklungsumgebung (IDE) IntelliJ oder das davon abgeleitete Android Studio.

Von meiner Seite gibt es daher auch die klare Empfehlung, mit der IntelliJ-Community-Edition für die ersten Beispiele zu arbeiten. Für Entwickler von Android-Apps gibt es wenig Gründe, nicht in Android Studio weiterzumachen und gegebenenfalls die entsprechende Kotlin-Unterstützung zu aktivieren.

Um kleine Code-Schnipsel einmal direkt in Aktion zu sehen, habe ich außerdem immer wieder auf die Online-Compiler unter https://try.kotlinlang.org zurückgegriffen.

2.2.1  Kotlin-Compi‌ler

Die grundlegendste Möglichkeit, Kotlin zu nutzen, ist der Kotlin-Compiler auf der Kommandozeile. Der Compiler wird dabei verwendet, um den bestehenden Code mit der Kotlin-Runtime zu bündeln und dann in ein ausführbares JAR zu konvertieren, welches mit einer Java-Umgebung lauffähig ist.

Darüber hinaus kann der Kotlin-Compiler auch als interaktive Shell oder zum Scripting verwendet werden.

Tipp

Zum Umgang mit dem Kotlin-Compiler und seiner Installation: https://kotlinlang.org/docs/tutorials/command-line.html

Die ersten Code-Beispiele kann man theoretisch auf diese Art ausführen, es ist aber an sich nicht zu empfehlen, da es keinerlei Unterstützung durch eine Umgebung gibt und auch das Management von Bibliotheken manuellen Aufwand bedeutet.

2.2.2  Kotlin-Compil‌er mit Gradle

Auf der Konsole kann auch das Buildsystem Gradle‌ die Arbeit an größeren Projekten vereinfachen. In beiden IDEs ist es dafür auch standardmäßig eingebunden. Gradle konfiguriert und managt die Abhängigkeiten eines Programms. So benötigt schon die einfachste »Hello world!«-Anwendung mindestens die Kotlin Runtime Library. Falls man unbedingt ohne eine Entwicklungsumgebung arbeiten wollte, wäre die Empfehlung, mindestens Gradle zusätzlich zu nutzen.

Tipp Gradle lokal installieren

Unter der domain https://gradle.org/ gibt es die Gradle Build Tools als Standalone-Software. Als nächster Schritt helfen dann die Getting Started Guides: https://gradle.org/guides/#getting-started.

In diesem Fall wird eine Konfigurationsdatei namens build.gradle erstellt, in der die Einstellungen festgehalten werden. Damit kümmert sich das Build Tool dann um den Download von Bibliotheken und Frameworks und konfiguriert den Kotlin/Java-Compiler entsprechend der gewünschten Einstellungen.

2.2.3  Integrierte Entwicklungsumgebungen/IDE

Kotlin ist als Multiplattform-Projekt nicht auf ein Tool festgelegt, aber für eine große Zahl an Umsteigern dürften die Produkte von JetBrains eine bekannte Referenz sein. Der Support im Tool (IntelliJ‌‌ ab Version 15, Android Studio‌‌ ab Version 3.0) entspricht dem Standard, der aus der Java-Entwicklung bekannt ist.

Dazu gehören Syntax Highlighting, Code completion und automatische Imports ebenso wie die von IntelliJ bekannten Inspections und Analysetools für den Code.

Wie es der Name schon nahelegt, ist die Android-Studio IDE auf Android-Apps festgelegt, weitergehender Support, wie zum Beispiel Projekt-Templates für eine JS-Anwendung, fehlet hier. Umgekehrt ist das allgemeine IntelliJ-Bundle mit allen notwendigen Komponenten für die komplette Android-Entwicklung ausgestattet.

IntelliJ‌ erlaubt auch die Entwicklung von Android‌-Anwendungen und zusätzlich auch die weiteren Verwendungen von Kotlin. Die Beispiele in diesem Buch sind größtenteils mit der IntelliJ-IDE und Android Studio entstanden. Beide IDEs sind unter bestimmten Bedingungen frei erhältlich.

Tipp: Download URLs

http://www.jetbrains.com/idea/download/index.html

https://developer.android.com/studio/

2.2.4  Konvertierung von existierendem Code

Eine sehr praktische Funktion – über beide IDE leicht zu erreichen – ist die Konvertierung von bestehendem Java-Quelltext‌‌‌ in Kotlin. So kann man die neue Sprache von bekanntem Terrain her erobern. Bei der Umsetzung entsteht in der Regel nicht die ideale Kotlin-Lösung, aber im besten Fall schon mal kompilierender und funktionierender Code.

Doch es gibt ein paar Aspekte zu beachten, die auch nach der automatischen Code-Konvertierung noch notwendig sind. Zum einen tut sich die Konvertierung mit komplexen if/switch-Anweisungen schwer und erzeugt bisweilen duplizierten Code.

Zum anderen wird die Konvertierung alle Unsauberkeiten in Bezug auf den Umgang mit Null-Sicherheit oder Typen aufdecken und damit unter Umständen auf relativ ungünstige bzw. teure Strukturen konvertieren, die besser manuell korrigiert werden. Zum Teil kam es hier bei meiner Arbeit an Projekten für das Buch auch zu Fehlern, die entweder nicht kompilierte oder aber Laufzeitfehler zeigten.

Last but not least entsteht auch im besten Fall Java-Code in Kotlin-Notierung. Die Paradigmen funktionaler Parameter werden also eher wenig bis gar nicht umgesetzt. Die Konvertierungsroutine erzeugt zum Beispiel veränderliche Variablen, die in Kotlin zum Beispiel besser als immutable deklariert werden sollten.

Kapitel 3: Kotlin by example

Die Konzepte von Kotlin bauen darauf, wohl strukturierten, gut testbaren und damit langfristig wartbaren Code zu erzeugen. Das gelingt am besten mit Quelltext, der seine Intention und die Lösungen nicht hinter großen Mengen redundanten Codes verbirgt. Es hilft vielleicht, das Mantra »Code ist Kommunikation« immer wieder leise aufzusagen, wenn es darum geht, die Wichtigkeit einer präzisen Lösung zu verstehen.

Durch die Zeilen, in denen die Lösung für ein mathematisches Problem oder die Regeln einer komplexen Benutzungsschnittstelle aufgeschrieben werden, kommunizieren Entwickler nicht nur mit der Maschine oder den Geräten, die diesen Code ausführen. Es handelt sich häufig auch um die Kommunikation mit dem zukünftigen Ich oder anderen Teammitgliedern, die auf den Funktionen aufbauen wollen. Noch komplizierter wird es, wenn die Kollegen später mit der Wartung beauftragt werden.

Hier spielen nachvollziehbare Architektur, gute interne Schnittstellen, automatische Tests und eine angemessene Dokumentation selbstverständlich eine große Rolle, doch last but not least natürlich vor allem der Sourcecode selbst.

In der Einführung wurde erwähnt, dass es das Ziel von Kotlin ist, concise oder präzise im Ausdruck zu sein. Das wird zum Teil über Sprach-Konstrukte und zum Teil über Konventionen und damit verbundene Kurzschreibungen erreicht. Zu den Mitteln zählen Annotationen, Lambdas (Funktionen ohne Deklaration und formale Einleitung, zum Beispiel als Parameter) und das Weglassen von Zeichen und Zeilen für bestimmte Kurzformen. Das Problem mit Kurzformen ist allerdings: Sie erschließen sich erst, wenn das Prinzip klar ist und führen zu Code, der nicht unbedingt auf den ersten Blick einsteigerfreundlich ist. Wer einmal ein drei Jahre altes Perl-Skript anpassen musste, weiß was ich meine.

Im ersten Schritt folgt trotzdem oder gerade deswegen der Sprung ins kalte Wasser. Das Ziel des Kapitels ist es, die grundlegenden Sprachkonstrukte und die Syntax kennenzulernen und zu erkennen. Neben den grundlegenden Schreib- und Denkweisen können dabei auch die wichtigsten Kurzformen schon einmal benutzt werden. Die Beispiele sollen helfen, sich überhaupt in Kotlin-Code zu orientieren, aber noch ohne Anspruch auf Vollständigkeit.