🖲 Découvrir Kotlin

Une histoire de syntaxe
Kotlin est un langage développé par Jetbrains, Jetbrains développe des environnements de développement pour pratiquement tous les langages les plus utilisés.
Kotlin en lui même est un langage fonctionnel et orienté objet. Là où java est 100% orienté objet, Kotlin permet plus de liberté d'utilisation et est ce qu'on appelle un langage moderne.
Il est bien moins verbeux que Java. Permet de faire moins d'erreur, produit des programmes plus stables, et est plus flexible.
Un exemple pour créer un POJO (ceux qui connaissent en Java sinon renseignez-vous c'est un principe de base) en Kotlin :
data class Customer(val name: String, val email: String, val company: String)
Et voila, cette ligne de code vous permet de créer une classe avec tout les getters, setters, equals()
, hashCode()
, toString()
et copy()
.
Fonctionnement
Kotlin permet de générer du bytecode pour JVM.
Un mot sur la JVM
La Java Virtual Machine est une belle invention qui date de 1995, et qui permet de faire un développement multi-plateforme. C'est un langage qui est compilé et interprété.

Lorsque vous codez en Java, votre code est compilé en byte code
ce n'est pas un état directement interprétable par votre ordinateur, mais interprétable par une JVM. On appelle ça le build time.
Ce byte code est ensuite interprété lorsque vous lancez votre application sur l'appareil cible, on appelle ça le runtime. D'où le besoin d'avoir un JRE
(Java Runtime Environment) pour executer un programme Java sur votre machine.
Mais le langage permet de compiler vers d'autres byte code
ou binary code
:
Javascript
C/C++
Swift
ObjectiveC
- Any native executable
Hello world
Comment coder en Kotlin pour apprendre ?
Vous avez l'embarras du choix:
- Via Intellijea IDE
- En ligne de commande via le compilateur Kotlin de votre système
- Via Gradle et mon tuto custom
- Via Kotlin Koans un cours en ligne interactif
- Via le Playground en ligne
- Via la documentation de Kotlin
Le Hello world
Dans le playground vous devriez avoir déjà une fonction main et le Hello world
//Kotlin
fun main() {
println("Hello world")
}
Voici le code équivalent en Java
//Java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
📝 Note Dans les deux cas il vous faut un point d'entréemain
à votre programme. En Kotlin c'est une simple fonction déclarée avec le mot cléfun
en java il vous faut une classe et à l'intérieur une méthodemain
Kotlin et le typage
Kotlin est un langage fortement typé.
Pour déclarer une variable en Kotlin
//On précise le type ici
val myHelloWorldStringVariable:String = "Hello there"
//Version alternative :
//L'inférence de type permet d'éviter d'expliciter le type
val myHelloWorldStringVariable = "Hello there"
📝 Note On peut déclarer une variable en dehors de toute fonction ou classe, ce qui n'est pas possible en Java
Voici le code équivalent en Java
public class HelloWorld {
String myHelloWorldStringVariable = new String("Hello there");
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Les variables
Pour déclarer une variable on peut utiliser 2 mots clés : val
et var
Optional & Null safety 🌮
Attention on arrive à un endroit légèrement difficile. Du moins c'est pas commun sur les langages que vous avez vu jusqu'à aujourd'hui.
En kotlin on ne peut pas avoir une valeur null
dans une variable. Contrairement au Java
. En Java on peut faire ca :
public class HelloWorld
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
OtherClass otherClass = null;
//Ici j'obtiens le fameux "Null pointer exception" lors du runtime
System.out.print(otherClass.myVar);
}
}
public class OtherClass {
String myVar = new String("Hello");
}
🚫 Si je compile ce code en Java, il va compiler (Buildtime) sans problème. Mais lorsque que je vais lancer mon programme (Runtime) il va planter.
Ce qui est pas top, car je ne vois le problème qu'au moment ou l'utilisateur va lancer le programme.
Essayons de faire la même chose en Kotlin
Ajoutez dans votre fichier (main.kt
) de test le code suivant :
fun main() {
val otherClassInstance = OtherClass()
println(otherClassInstance.myVar)
}
class OtherClass(var myVar:String = null)
🚫 C'est impossible. En Kotlin si on indique pas explicitement qu'une variable peut contenir une valeur null
alors il est impossible de build
.
Comment on indique cela alors ?
Si je voulais que le build time passe sur mon code Kotlin, il faudrait que je modifie en faisant cela :
fun main() {
val otherClassInstance = OtherClass()
println(otherClassInstance.myVar)
}
//On a rajouté un signe "?" derrière notre type.
//Cela indique au compilateur que cette variable est parfois "null"
class OtherClass(var myVar:String? = null)
Non seulement cela compile, mais au runtime cela ne plante pas, même si votre variable est null
.
Comment gérer ce comportement ?
Souvent dans votre code vous allez devoir indiquer au programme que vous n'êtes pas certain qu'il y aura une valeur non null dans une variable à un instant T (Ex: je récupère une donnée du réseau)
Dans ce genre de cas, vous allez devoir unwrap 🌮
la variable, c'est en gros "Découvrir" ce qu'il y a dedans, et suivant ce que vous trouverez, exécutez tel ou tel code.
Si je prend l'exemple du réseau, imaginez le code suivant
//Je vais stocker la réponse hypothétique du réseau dans ma variable
var myNetworkResponse:String? = null
//Ici j'appelle le réseau, et il renvoi une valeur (ou PAS)
myNetworkResponse = networkCall()
//Je veux récuperer la réponse du réseau si il y en a unne
myNetworkResponse?.let {
//La fonction `let` permet de unwrap 🌮 votre variable
//Elle produit une valeur non optionnel "it" par defaut
saveNetworkResponseToDataBase(it)
//"it" est certain d'exister, et est non null
}
Note 📝 Cette fonction n'existe pas, on vous demande à partir du code ci-dessus d'imaginer sa signature
Note 📝 Le même exemple mais avec le nommage explicite de la donnée unwrap 🌮
//On donne un nom explicite "responseData" au lieu de "it"
myNetworkResponse?.let { responseData ->
//La fonction `let` permet de unwrap 🌮 votre variable
saveNetworkResponseToDataBase(responseData)
}
On a vu la fonction let
mais il en existe d'autres pour gérer les optionnels et le null safety
Pour en apprendre plus voici un lien vers la documentation Kotlin qui explique ce comportement et comment l'utiliser au mieux.
Attention ⚠️
A l'inverse vous pouvez forcer le compilateur à ignorer qu'une variable est potentiellement null
Grâce au symbole !!
: il est à éviter le plus possible car il force le compilateur à ne pas vérifier si cette variable est vide avant de l’utiliser.
Cela peut être pratique pour éviter l’unwrapping 🌮
et donc quelques lignes de code, mais c’est aussi très dangereux car le comportement est imprévisible.
//On bourrine. Mais si le network plante, le programme plante.
saveNetworkResponseToDataBase(myNetworkResponse!!)

Les fonctions
En Kotlin vous pouvez déclarer des fonctions n'importe où dans votre programme. Une fonction peut aussi être dans une variable, comme en javascript
.
fun myFunction()
fun myFunction(): String {
return "Hello World"
}
//Type inference, Kotlin devine que la fonction sera de type string.
//On utilise également la syntaxe simplifiée pour une fonction ici
fun myFunction() = "Hello world"
//Avec un parametre, les parametres doivent-etre typé
fun numberOfCharactersInString(inputString: String): Int {
return parameter.length
}
fun greetUser(name: String, lastname:String, city:String) {
println("Hello $name $lastname, you live in $city")
}
//Lambda dans une variable
var myVariable = {
println("Hello")
}
//On peut aussi passer des parametres
var myVariable:(name: String) -> Unit = {name ->
println("Hello $name")
}
//Fonction anonyme ex 1
val square = fun(x: Int) = x * x
//Fonction anonyme ex 2
val greetings = fun(name: String) = "Hello $name"
Puisque Kotlin est aussi un langage fonctionnel, il est important de bien comprendre comment et quand utiliser des fonctions. Nous verrons tout au long de l'introduction différents moyens d'utiliser les fonctions et variables.
Note 📝: La syntaxe pour concatener unestring
est+
ou à l'intérieur des double quote vous pouvez utiliser"Je concatene avec $maVariable"
. Et pour accéder a une propriété de votre variable :"Je concatene avec ${maVariable.maProp}"
Appeler une fonction
Il existe plusieurs façon d'appeler une fonction en Kotlin, notamment au niveau des paramètres.
numberOfCharactersInString("Hello"); //5
//J'appelle ma fonction en précisant le nom des parametres
numberOfCharactersInString(inputString = "Hello")
Control flow (if
, for
, when
)
Je ne vais pas paraphraser la documentation qui fait très bien son boulot ici.
switch
en Kotlin ?
string
et affichez chaque valeur dans la sortie console. Faites valider par l'enseignant.
Les classes
Kotlin est aussi un langage objet, on déclare une classe qui possède une propriété comme ceci :
//Le constructeur est dans la signature de la classe entre ()
class MyClass(val myProperty:String?)
//Pour instancier cette classe
val myClassInstance = MyClass("hello")
Ou
class MyClass {
var myVar:String? = null
constructor(myVarValue: String?){
myVar = myVarValue
}
}
Sans propriété :
class MyClass
Voici le code équivalent en Java
class MyClass {
String myProperty;
public MyClass(String myProperty){
this.myProperty = myProperty;
}
}
Il est très rapide et concis de créer une classe en Kotlin. Et puisque c'est un langage assez malin il y a pas mal de raccourcis sous forme de mot clés.
Les classes de données
Un concept qui n'existe pas partout, les data class
sont en fait un type de classe dédié au stockage de la donnée.
La différence avec les classes normales est que le compilateur va vous créer automatiquement des fonctions utilitaires sur vos data class
.
Les fonctions automatiquement générées :
equals()
toString()
hashCode()
copy()
...
Retrouvez la documentation sur les data class
Exemple de data class
data class User(val name: String, val age: Int, val gender: Gender)
val myUser = User(name = "Roger", age = 21, gender = Gender.MALE)
//To string est généré automatiquement donc tout va bien
println(myUser)
Encore une fois on remarque qu'un mot clé du langage va nous permettre de gagner du temps sur le développement tout en gardant des concepts standards.
Remarquez le typeGender
, c'est unenum
en Kotlin vous pouvez utiliser ce genre de variable pour définir un set de valeur prédéfini pour un objet.
Classes Enum
Très simple a comprendre mais redoutablement efficace pour construire un programme très robuste, les classes enum
permettent de lister des valeurs possibles d'un type donné.
Exemple avec notre Gender
enum class Gender {
FEMALE,
MALE,
OTHER
}
Cela permet d'éviter d'hardcoder des valeurs et d'éviter d'utiliser des constantes String
qui sont fastidieuses à travailler et génératrice d'erreur.
data class User(val name: String, val age: Int, val gender: Gender)
val user1 = User(name = "Roger", age = 21, gender = Gender.FEMALE)
Ainsi toute variable ayant le type Gender
ne pourra prendre qu'une des 3 valeurs de l'enum
possible.
enum
qui vous permettrait de simplifier un problème ?
Les mots clés
Companion, Object, Lateinit, let, with, run
ne représentent qu'une partie émergée de l'iceberg.
Kotlin est un langage avec beaucoup de mots-clés 🔑🔑🔑 , en voici une référence.
Pourquoi autant de mot clés ? Pour que vous écriviez le moins de code possible, la vision derrière Kotlin c'est la concision tout en conservant la clarté du code. Chaque mot clé est un travail redondant qui est optimisé par le compilateur et donc évite au développeur d'écrire du code. Plus on écrit de code, plus on a de chance de faire des erreurs.
Aller plus loin
Pour apprendre et maitriser un nouveau langage, il n'y a pas de solution simple.
Il faut vous entrainer Pour le dernier exercice, on va s'entrainer un peu.
Allez sur le site Kotlin Koans en cliquant sur le lien et réalisez les exercices à partir de la section "Conventions".

Next Step : Gradle
Pour attaquer la suite et comprendre le mécanisme derrière la compilation d'une app Android nous devons regarder Gradle de plus près.
Réalisez la fiche suivante : Introduction à Gradle.