Im finnischen Meerbusen liegt die kleine Insel Kotlin. Seit rund einem Jahr hat sie eine Namensvetterin: Kotlin heißt auch die neue Programmiersprache, die sich zu einer Java-Alternative entwickeln soll.
Die Firma Jetbrains kennen Programmierer vermutlich als Hersteller der IDE Intelli-J [1]. Deren Entwickler störten sich bei ihrer Arbeit immer wieder an einigen Eigenheiten von Java. Da es ihrer Ansicht nach schwierig wäre, Java entsprechend zu verbessern, schufen sie kurzerhand ihre eigene Sprache. Die soll vor allem mit Java kompatibel bleiben, sich mindestens genauso schnell übersetzen lassen, alte Ärgernisse wie die lästigen Null-Pointer-Exceptions (NPEs) abschaffen, flexibler sein sowie eine kompaktere Syntax besitzen. Heraus kam Kotlin [2].
Mischmaschine
Ausgelegt ist Kotlin als Vielzweck-Programmiersprache (General Purpose Language), die vor allem für größere Projekte in Unternehmen gedacht ist. Jetbrains selbst möchte mit ihr die Entwicklung von Intelli-J vereinfachen [3]. Kotlin übernimmt einen großen Teil der Syntax von Java, folglich ist es objektorientiert, statisch typisiert und bietet Generics. Hinzu mischen die Erfinder aber auch Elemente aus funktionalen Sprachen, etwa Funktionen höherer Ordnung. Die Syntax kurz und knackig halten sollen unter anderem Mixins und eine automatische Typableitung.
Den Quellcode überführt ein Compiler in Java-Bytecode, der wiederum auf jeder Java Virtual Machine (JVM) läuft. Kotlin kann dadurch Java-Bibliotheken nutzen und umgekehrt auch Java Kotlin-Code einbinden. Damit darf der Programmierer beliebte und leistungsfähige Java-Frameworks wie Spring oder Hibernate weiterverwenden. Mittlerweile erzeugt der Compiler auf Wunsch auch Javascript-Code, das Ergebnis läuft dann in jedem Browser. Kotlin steht zusammen mit der Referenzimplementierung des Compilers seit Februar 2012 unter Apache-2.0-Lizenz.
Guten Tag!
Das Hallo-Welt-Beispiel aus Listing 1 dürfte für Java-Programmierer gewöhnungsbedürftig aussehen: »fun« definiert eine neue Funktion, die in diesem Fall »main()« heißt. Wie auch in vielen anderen Sprachen bildet sie den Einsprungspunkt in das Programm und ist folglich in jedem Kotlin-Programm Pflicht. Im Gegensatz zu Java ist die »main()« -Funktion jedoch nicht explizit in einer Klasse gekapselt. In Listing 1 besitzt »main()« einen einzigen Parameter namens »args« vom Typ »Array<String>« – zu diesem kryptischen Gebilde später noch mehr. Die Funktion »println()« gibt wie in Java den ihr übergebenen Text aus. Semikolons am Ende einer Zeile sind in Kotlin nicht erforderlich.
Listing 1
hallowelt.kt
01 fun main(args : Array<String>) {
02 println("Hallo Welt!")
03 }
Um das Beispiel zu übersetzen, spielt man das Java Development Kit (JDK) über den Paketmanager ein und angelt sich dann den Kotlin-Compiler von Github [4]. Es ist lediglich das unter “Kotlin Compiler M2” angebotene Zip-Archiv erforderlich, das einen Schnappschuss der laufenden Entwicklung enthält. Die folgenden Ausführungen basieren auf der zum Redaktionsschluss aktuellen Version 0.1.2580. Nachdem der Anwender das Archiv entpackt hat, macht er das Skript »kotlinc-jvm« ausführbar:
chmod +x ./kotlinc/bin/kotlinc-jvm
Jetzt lässt sich der Quellcode in der Datei »hallowelt.kt« übersetzen:
./kotlinc/bin/kotlinc-jvm -output hallowelt-src hallowelt.kt
Der Compiler legt dabei ein Unterverzeichnis »hallowelt/« mit einer ».class« -Datei an, die den Bytecode enthält (Abbildung 1). Diesen übergibt der Benutzer an eine ganz normale JVM:

Abbildung 1: Kotlin erzeugt Java-Bytecode, den der Anwender mit einer Java Virtual Machine ausführen muss.
java -cp ./kotlinc/lib/kotlin-runtime.jar:./hallowelt namespace
Der Parameter »-cp« für den Classpath bindet die Kotlin-Runtime-Bibliothek »runtime.jar« und das »hallowelt« -Verzeichnis ein. Java-Kenner dürften zudem entdecken, dass der Kotlin-Compiler die »main()« -Funktion in einer Java-Klasse namens »namespace« verpackt. Alternativ kann man auch Runtime und Kotlin-Programm zu einem kompakten »jar« -Archiv verschnüren, was die Weitergabe vereinfacht:
./kotlinc/bin/kotlinc-jvm -jar hallowelt.jar -src hallowelt.kt -includeRuntime
In den Tests für diesen Artikel funktionierte das Zusammenfassen allerdings nicht, der Start des Programms gelang weiterhin nur über die Angabe der lokalen Laufzeitumgebung:
java -cp ./kotlinc/lib/kotlin-runtime.jar:./hw.jar namespace
Alle weiteren Parameter des Compilers liefert die »-help« -Option. Wer Javascript produzieren möchte, der ersetzt den Compiler-Aufruf »kotlinc-jvm« einfach durch dessen Kollegen »kotlinc-js« . Auf der Kotlin-Homepage können Neugierige das auch einfach einer Webanwendung überlassen, die das Resultat wahlweise auf dem Server oder im Browser ausführt (Abbildung 2). Wer integrierte Entwicklungsumgebungen bevorzugt, wird im Kasten “Intelli-J mit Kotlin-Plugin” fündig.
Entwicklungsumgebung: Intelli-J mit Kotlin-Plugin
Jetbrains bietet für seine hauseigene Entwicklungsumgebung Intelli-J (Abbildung 3) ein passendes Kotlin-Plugin an, das die IDE ab Version 11.1 voraussetzt. Die unter [1] kostenlos erhältliche Community Edition reicht dazu aus. Nach dem Entpacken des Archivs startet der Anwender das Skript »idea.sh« im Unterverzeichnis »bin« . In der erscheinenden Abfrage belässt er die Voreinstellung und klickt auf »OK« .
Um das Plugin zu installieren, ruft er im Hauptfenster »File | Settings …« auf, markiert im erscheinenden Fenster in der linken Spalte den Punkt »Plugins« und klickt auf »Browse repositories …« . In der Liste findet sich der Eintrag »Kotlin« . Ein Doppelklick auf den Namen veranlasst die Installation. Nach einer kurzen Wartezeit sollte das Kotlin-Plugin in der mittleren Spalte auftauchen. Das Einstellungsfenster schließt der Benutzer mit »OK« und startet die IDE per »Restart« neu.
Um ein neues Kotlin-Projekt zu initiieren, wählt der Programmierer »File | New Project« , markiert »Create project from Scratch« , klickt auf »Next« , vergibt einen Projektnamen (etwa »hallowelt« ), belässt alle übrigen Einstellungen und klickt zweimal auf »Next« . Wenn Intelli-J jetzt eine leere Liste zeigt, konnte es das (richtige) Java Development Kit nicht finden. Dann hilft es, unter »Configure« das Verzeichnis des JDK von Hand einzustellen. Ein Klick auf »Finish« beendet das Anlegen, und nach einer Weile erscheinen die Dateien des neuen Projekts in einer Baumdarstellung.
Auf den »src« -Ordner klickt der Entwickler mit der rechten Maustaste, wählt »New | Kotlin File« und vergibt einen Dateinamen, etwa »hallowelt« . Intelli-J bietet jetzt am oberen Rand des Quelltextes an, das Modul als »JVM Kotlin Modul« einzurichten, was ein Klick auf den Link bejaht. Die Datei »hallowelt.kt« nimmt nun Kotlin-Code auf – etwa den aus Listing 1. Bei der Eingabe vervollständigt Intelli-J den Code automatisch. Um das Programm zu starten, klickt der Programmierer im Projektbaum die Datei »hallowelt.kt« an und wählt »Run ‘namespace’« .
Variable Schleifchen
Bei der Deklaration von Variablen muss der Programmierer in Kotlin aufpassen: Eine mit »var« deklarierte Variable lässt sich nachträglich ändern, eine mit »val« hingegen nicht. Der folgende Dreizeiler würde somit zu einem Fehler beim Kompilieren führen:
var a = "Hans" val b = "Klaus" b = a;
Eine Typangabe ist nur notwendig, wenn der Compiler den Typ nicht selbst herleiten kann oder der Entwickler ihn aufgrund der besseren Lesbarkeit explizit angeben möchte. Dann steht der Typ hinter einem Doppelpunkt:
var name : String
Neben dem »String« kennt Kotlin noch die üblichen Verdächtigen, darunter »Float« (Fließkommazahl), »Int« (Ganzzahl) und »Boolean« .
Die Kontrollstrukturen If & Co. verhalten sich wie ihre Kolleginnen aus Java. Eine Ausnahme stellt das eingebaute Pattern Matching dar, das verschachtelte Ifs beziehungsweise das aus C bekannte »switch« ersetzt:
val sprache = "DE"
val gruss = when (sprache) {
"EN" -> "Hello!"
"DE" -> "Tag!"
else -> "Sprache unbekannt"
}
println(gruss)
In diesem Beispiel testet Kotlin den Inhalt von »sprache« auf die vor dem »->« stehenden Texte. Bei Übereinstimmung liefert »when« das Ergebnis rechts von »->« .
Auch »for« -Schleifen vereinfacht Kotlin gegenüber Java, das folgende Beispiel gibt alle Zahlen von 1 bis 10 aus:
for (zaehler in 1..10) println(zaehler)
Nach »in« muss übrigens immer ein Objekt folgen, das über einen Iterator verfügt, etwa eine Liste oder ein Array. Die Notation »1..10« stellt dies im Beispiel oben sicher.
Funktional
Den Rückgabewert einer Funktion notiert der Kotlin-Coder direkt vor der öffnenden geschweiften Klammer:
fun sum(x : Int, y : Int) : Int {
return x+y
}
Bislang durfte eine Funktion sogar mehrere Werte gleichzeitig in einem Tupel zurückliefern. Die Entwickler haben jedoch bereits angekündigt, die Tupel in einer der nächsten Sprachversionen zu streichen. Nach wie vor kann Kotlin den Rückgabetyp selbst ermitteln, was folgende Kurzschreibweise ermöglicht:
fun sum(x : Int, y : Int) = x + y
Kotlin erlaubt außerdem, Funktionen an Funktionen zu übergeben oder sie als Resultat von Funktionen zu liefern, die dadurch Funktionen höherer Ordnung darstellen:
fun rechne(x : Int, y : Int, machwas : (Int, Int) -> Int) : Int {
return machwas(x,y)
}
Die Funktion »rechne()« erwartet, dass sie neben zwei Integerwerten auch eine Funktion übergeben bekommt. Diese Funktion kennt »rechne()« unter dem Namen »machwas« . Sie nimmt ebenfalls zwei Integerwerte entgegen »(Int, Int)« und gibt einen Integerwert aus: »-> Int« . »rechne()« ruft »machwas()« mit »x« und »y« auf, was schließlich den von ihr berechneten Wert liefert. Man könnte also beispielsweise einfach zwei Zahlen addieren lassen:
rechne(2,3, {a, b -> a + b})
In den geschweiften Klammern steht eine Funktion ohne Namen, eine so genannte anonyme oder Lambda-Funktion. Hier nimmt sie zwei Zahlen »a« und »b« entgegen und liefert die Summe der beiden zurück.
Klassik
Die Definition einer Klasse zeigt Listing 2. Deren Konstruktor erwartet zwei Parameter (»vorname« und »nachname« ), die sie in den öffentlichen Variablen »Vorname« und »Nachname« speichert. Den Zugriff auf ein Attribut kann der Programmierer abfangen, indem er unterhalb des entsprechenden Attributs eine Methode namens »get()« platziert.
Listing 2
Klassen-Definition
01 class Adresse(vorname : String, nachname : String) {
02 public var Vorname : String = vorname
03 public var Nachname : String = nachname
04 get() = "Meier"
05 private val anrede = "Hallo $Vorname $Nachname"
06
07 fun gruss() {
08 println(anrede)
09 }
10 }
11
12 fun main(args : Array<String>) {
13 var paul = Adresse("Paul", "Schmidt")
14 paul.gruss()
15 }
In Listing 2 geschieht dies beim Nachnamen: Wer die Variable »Nachname« auslesen möchte, aktiviert zwangsweise die Funktion »get()« und bekommt den Text »Meier« zurückgeliefert – egal welchen Wert die Variable »Nachname« tatsächlich besitzt (Abbildung 4).

Listing 2
zwingt das Programm dazu, als Nachname stets "Meier" auszugeben.” width=”300″ height=”190″ /> Abbildung 4: Die Methode »get()« in Listing 2 zwingt das Programm dazu, als Nachname stets “Meier” auszugeben.In Listing 2 nutzt »get()« wieder die Kurzschreibweise für Funktionen. Analog lassen sich mit der Methode »set()« auch Schreibzugriffe auf die Variable abfangen. Hier genügen »get()« und »set()« als Methodennamen: Kotlin bezieht die Methode immer automatisch auf das direkt darüber stehende Attribut. Wer keine Getter- und Setter-Methoden benötigt, darf die Attribute auch direkt im Konstruktor deklarieren (Listing 3)
Listing 3
Deklaration im Konstruktor
01 class Adresse(var Vorname : String, var Nachname : String) {
02 private val anrede = "Hallo $Vorname $Nachname"
03 [...]
Das dritte Attribut »anrede« ist »private« , also nicht von außen zugänglich. »$Vorname« und »$Nachname« ersetzt Kotlin automatisch gegen den Inhalt der gleichnamigen Variablen. Dank dieser Dollar-Notation lassen sich Strings rasch zusammensetzen. Um eine Klasse zu instanziieren, ruft der Entwickler einfach ihren Konstruktor auf – das in anderen Sprachen übliche Schlüsselwort »new« fehlt in Kotlin:
val paul = Adresse("Paul", "Schmidt")
Klassen sind in Kotlin grundsätzlich »final« , sie lassen sich also nicht ableiten. Um dennoch eine Vererbung zu ermöglichen, muss sie der Programmierer explizit öffnen, und zwar sowohl die beteiligten Klassen als auch jede Methode, die ein Erbe überschreibt.
Familienplanung
Listing 4 zeigt dazu ein Beispiel. Dort lassen sich die Basisklasse »Punkt« und ihre Methode »zeichne()« überschreiben. Davon macht wiederum die Klasse »Rechteck« Gebrauch. Sie erbt von »Punkt« und überschreibt die Methode »zeichne()« , erkennbar am Schlüsselwort »override« . Auf die Methoden und Attribute der Basisklasse greift der Entwickler über das Schlüsselwort »super« zu. Den Konstruktor der Basisklasse ruft er hinter dem Doppelpunkt und vor der öffnenden geschweiften Klammer auf.
Listing 4
Vererbung in Kotlin
01 open class Punkt(var x : Int, var y : Int) {
02 open fun zeichne() {println("$x,$y")}
03 }
04
05 open class Rechteck(x : Int, y : Int, var laenge : Int) : Punkt(x,y) {
06 final override fun zeichne() {
07 super.zeichne()
08 println("$laenge")
09 }
10 }
Während man in Listing 4 von »Rechteck« weitere Klassen ableiten könnte, ließe sich ihre Methode »zeichne()« aufgrund des »final« jedoch nicht noch einmal überschreiben.
An die Stelle der Interfaces aus Java treten so genannte Traits. Sie dürfen nicht nur die Methoden-Signaturen, sondern auch Methoden-Implementierungen enthalten. Im Gegensatz zu Klassen besitzen Traits jedoch keine Attribute und somit auch keinen Zustand.
Listing 5 zeigt dafür ein Beispiel. »Vogel« ist dort ein Trait, das in »Elster« implementiert ist. Die Klasse »Elster« verpflichtet sich damit, die von »Vogel« vorgegebenen Methoden anzubieten – bis auf die Methode »singe()« , denn die hat »Vogel« bereits für die Klasse »Elster« implementiert. »Any« ist die Basisklasse, von der grundsätzlich alle anderen Klassen abgeleitet sind, »esse()« erwartet somit ein beliebiges Objekt als Parameter.
Listing 5
Beispiel für Traits
01 trait Vogel {
02 fun fliege(geschwindigkeit: Int)
03 fun esse(nahrung: Any)
04
05 fun singe() {
06 println("Piep");
07 }
08 }
09
10 class Elster : Vogel {
11 override fun fliege(geschwindigkeit: Int) {
12 [...]
13 }
14 override fun esse(nahrung: Any) {
15 [...]
16 }
17 }
Traits
In Listing 6 nutzt die Klasse »Garage« ein Objekt, das das Trait »Auto« implementiert. Der »Inhalt« könnte ein VW oder eine andere Marke sein. Dank der so genannten First-Class-Delegation lässt sich die »Garage« aber kompakter schreiben – »Garage2« zeigt wie: Das Schlüsselwort »by« teilt dem Compiler mit, dass er die Funktionalität des Trait »Auto« an das im Parameter »inhalt« übergebene Objekt weiterreichen (delegieren) soll.
Listing 6
First-Class-Delegation
01 trait Auto {
02 fun fahre() : String
03 }
04
05 class VW : Auto {
06 override fun fahre() = "Brumm"
07 }
08
09 class Garage(inhalt : Auto) {
10 var Inhalt = inhalt;
11
12 fun oeffnen() : String {
13 return Inhalt.fahre()
14 }
15 }
16
17 class Garage2(inhalt : Auto) : Auto by inhalt {
18 fun oeffnen() : String {
19 return fahre()
20 }
21 }
Das hat den Vorteil, dass der Programmierer das Objekt nicht mehr explizit in einem Attribut ablegen muss und zudem die Methoden des Trait direkt aufrufen kann. Anders als Java erlaubt Kotlin das Überladen von Operatoren. Listing 7 zeigt ein Beispiel: Beim Addieren der zwei Objekte »a + b« ruft Kotlin automatisch die Methode »a.plus(b)« auf.
Listing 7
Überladen des +-Operators
01 class Geschwindigkeit(var geschw : Int) {
02 fun plus(nocheine : Geschwindigkeit) : Int {
03 geschw += nocheine.geschw
04 return geschw
05 }
06 }
07
08 [...]
09 var a = Geschwindigkeit(12)
10 var b = Geschwindigkeit(18)
11 println( a + b )
Mit der so genannten Object Declaration lässt sich ganz einfach das Singleton-Entwurfsmuster umsetzen:
object Einzeln {
public var farbe : String = "rot"
fun faerben(f : String) { farbe = f }
}
Damit entsteht umgehend ein Objekt »Einzeln« . Der Entwickler kann es nicht einer Variablen zuweisen, sondern nur direkt mit ihm arbeiten:
println(Einzeln.farbe)
Einzeln.faerben("gruen")
Wer eine Liste für Zahlen und eine Liste für Strings benötigt, müsste eigentlich zwei verschiedene Klassen schreiben. Da dies recht umständlich ist, sind die so genannten generischen Typen oder Generics entstanden. Java kennt sie mittlerweile und in C++ sind sie schon länger als Templates bekannt.
Auch Kotlin bietet Generics, ein passendes Beispiel liefert Listing 8. Die Klasse »Papierkorb« merkt sich einfach das ihr übergebene Objekt. »T« ist dabei ein Platzhalter für den hier noch unbekannten Typ. Im unteren Teil von Listing 8 entsteht ein neuer »Papierkorb« , der ausschließlich »String« -Objekte aufnimmt. Der Typ der Variablen »muell« ist »Papierkorb<String>« .
Listing 8
Generics
01 class Papierkorb<T> (einwurf : T) {
02 var Inhalt = einwurf
03 }
04
05 [...]
06 var muell = Papierkorb<String>("Rechnung")
07 println(muell.Inhalt)
Listen und Arrays
Bereits an Bord hat Kotlin die generischen Klassen »List« und »Array« . Die folgenden Zeilen legen ein Array »a« mit den drei Zahlen 1, 2 und 3 an und geben dann das erste Element aus:
var a = Array<Int> (3, {i -> i + 1})
println(a[0])
Alternativ zieht der Kotlin-Programmierer auch die Hilfsfunktion »array()« heran. Sie erzeugt automatisch ein passendes »Array« -Objekt:
var b = array(1, 2, 3)
Einer Klasse lassen sich auch nachträglich noch Funktionen hinzufügen (Mixin). In Listing 9 erhält die Klasse »Auto« noch eine Methode »schneller()« . Diese wiederum greift auf die Attribute und Funktionen der Klasse »Auto« über das Schlüsselwort »this« zu. Das ganze Konzept nennen die Kotlin-Entwickler Extension Functions. Dieses Anheften von Funktionen ist besonders nützlich bei Generics, also etwa einer Liste, die etwas Besonderes können soll:
Listing 9
Extension Functions
01 class Auto {
02 public var Geschwindigkeit : Int = 0
03 }
04
05 fun Auto.schneller(geschw : Int) {
06 this.Geschwindigkeit = geschw
07 }
08
09 [...]
10 var vw = Auto()
11 vw.schneller(10)
12 println(vw.Geschwindigkeit)
fun List<String>.machwas() { ... }
In Java sind »List<String>« und »List<Object>« zwei komplett verschiedene Klassen. Die Objekte in »List<String>« lassen sich nicht einfach in »List<Object>« stecken, auch wenn »Object« die Basisklasse von »String« ist. Abhilfe schaffen in Java die kryptischen Wildcards, in Kotlin genügt das simple Schlüsselwort »out« . Ein Beispiel zeigt Listing 10: Die Funktion »anzahl()« nimmt einen »Behaelter<String>« entgegen, den sie anschließend in der Variablen »krimskrams« speichert – welche aber eigentlich vom allgemeineren Typ »Behaelter<Any>« ist.
Listing 10
Declaration Site Variance
01 class Behaelter<out T>(var elem : T) {
02 [...]
03 }
04
05 fun anzahl(woerter : Behaelter<String>) {
06 val krimskrams : Behaelter<Any> = woerter
07 [...]
08 }
Das Spiel funktioniert allerdings nur in dieser Richtung: Die aus dem »Behaelter« herausfallenden Objekte kann man nur in ein anderes Objekt stecken, für den umgekehrten Weg ist anstelle von »out« das Schlüsselwort »in« zuständig. In jedem Fall müssen sich die Objekte in den jeweils anderen Typ wandeln lassen, in Listing 10 nimmt etwa »Behaelter<Any>« beliebige Objekte (»Any« ) auf. Das komplette Konzept bezeichnen die Kotlin-Entwickler als Declaration Site Variance.
Nullrunde
In Java können Variablen den Wert »null« enthalten und somit auf kein Objekt verweisen. Versucht ein Programm dennoch auf ein nicht vorhandenes Objekt zuzugreifen, führt das zu einer gefürchteten Null-Pointer-Exception (NPE). Kotlin-Programmierer dürfen deshalb »null« einer Variablen erst gar nicht zuweisen. Wer das dennoch unbedingt möchte, muss dies explizit mit einem Fragezeichen hinter dem Typ anzeigen:
var b : String? = "hallo" b = null
Selbst wenn der Programmierer die Zuweisung von »null« erlaubt, fängt der Compiler verschiedene Situationen ab, in denen ein Zugriff auf eine »null« -Referenz möglich wäre. Auch hier muss der Code stets explizit mit »b?.length()« den Aufruf gestatten – womit ein Laufzeitfehler droht (Abbildung 5). Wer das im Hinterkopf behält, bindet vorhandenen Java-Code mit »import« ein und ruft ihn direkt im Kotlin-Code auf. Sogar »for« -Schleifen funktionieren bei Java-Collections:
import java.util.*[...] var javaliste = ArrayList<String>()[...] for (elem in javaliste) println(elem)
Kotlin wirft also ein paar unangenehme Eigenschaften von Java über Bord und holt ein paar interessante Konzepte von Groovy und Scala hinzu.
Großbaustelle
Wer sich mit der Sprache beschäftigt, begibt sich allerdings auf eine Großbaustelle, eine stabile Syntax ist noch nicht in Sicht. Kotlins Väter scheuen im Moment auch nicht davor zurück, einige Sprachelemente wieder zu verwerfen. Bestes Beispiel sind die Tupel [5]. Viele andere Features sind geplant und entstehen sukzessive, etwa die Annotations ([6], Abbildung 6). Es gibt sogar erste Versuche, Kotlin als Skriptsprache und somit Bash-Ersatz einzusetzen [7].

Abbildung 6: Vorsicht, Baustelle! Annotations gehören zu den Kotlin-Features, die sich noch in Entwicklung befinden, wie die Onlinedokumentation zeigt.
Jeder Kotlin-Nutzer darf die Sprachelemente direkt in der Dokumentation kommentieren. Die Entwickler lesen dort mit und beantworten Fragen extrem flott, sachliche Anregungen sind erwünscht. Dank der langjährigen Praxiserfahrung der Entwickler mit Java stehen zudem die Chancen recht gut, dass Kotlin kein Rohrkrepierer wird. Die neue Sprache wäre eine interessante Alternative für alle, denen Java zu altbacken und Scala zu kompliziert ist. (mhu)
Infos
- Intelli-J: http://www.jetbrains.com/idea/
- Kotlin: http://confluence.jetbrains.net/display/Kotlin
- Gründe, die zur Entwicklung von Kotlin führten: http://blog.jetbrains.com/kotlin/2011/08/why-jetbrains-needs-kotlin/
- Kotlin-Compiler auf Github: https://github.com/JetBrains/kotlin/downloads
- Tupel in Kotlin: http://confluence.jetbrains.net/display/Kotlin/Tuples
- Annotations in Kotlin: http://confluence.jetbrains.net/display/Kotlin/Annotations
- Kotlin als Skriptsprache: https://github.com/andrewoma/kotlin-script
- Listings zu diesem Artikel: https://www.linux-magazin.de/static/listings/magazin/2012/11/kotlin








