15. Cos’è Kotlin?
Kotlin è un linguaggio, sviluppato da un team di JetBrains pensato
appositamente per lavorare con JVM e JavaScript e risolvere le effettive
esigenze degli sviluppatori.
È un linguaggio ad oggetti, con supporto per funzioni di ordine superiore
(e lambda), e possiede molti costrutti comuni ai linguaggi funzionali.
17. In modo pratico
Java
class JavaClass{
private final int x = 1;
private int y = 2;
public int getX(){ return x; }
public int getY(){ return y; }
public void setY(int y){
this.y = y;
}
}
Kotlin
public class KotlinClass{
val x: Int = 1
var y = 2
}
18. Inferred datatypes
public class User{
val name = "Erik"
val surname = "Minarini"
var age = 25
fun birthday(){
age ++
}
}
Il tipo di dato puo’ essere dedotto dal contesto o dal primo assegnamento
19. Custom getter / setter
Getter e Setter sono opzionali, se non specificati in altro modo sono autogenerati.
var isEmpty: Boolean = true
E’ equivalente a
var isEmpty: Boolean = true
get() = field
set(value){field = value}
20.
21.
22. Custom getter / setter
class Contact() {
var number: String = ""
var firstName: String? = null
set(value) {
field = value.toLowerCase()
}
private val hasPrefix : Boolean
get() = number.startsWith("+")
}
23. Costruttore e init
class Person constructor(firstName: String) {}
La keyword constructor puo’ essere omessa se non ha modificatori di visbilita’
class Person(firstName: String) {}
24. Costruttore e init
Il costruttore non contiene codice, il codice di inizializzazione si puo’ inserire nel
blocco init
class Customer(name: String) {
init {
logger.info("Customer initialized with value ${name}")
}
}
26. When Expression
In Kotlin il costrutto switch viene sostituito da when
when (x) {
1 -> println("is one")
2 -> println("is two")
else -> {
println("nope!")
}
}
28. When Expression
oppure senza argomenti, come una serie di if
val result = when {
x in 1..10 -> "in range"
s.contains("hello") -> "it's a welcome!"
v is ViewGroup -> "it's a ViewGroup"
else -> "nope!"
}
30. Data classes
Spesso creiamo classi che non fanno nulla ma contengono dati.
public class Auto{
public String modello;
public String targa;
public Auto(String modello, String targa){
this.modello = modello;
this.targa = targa;
}
}
32. Data classes
Ma in Kotlin...
data class Auto(val modello: String, val targa: String)
Vengono anche generate alcune funzioni “base” come toString,
copy(), equals(), etc...
33.
34. Data classes
Java
class Song{
private String title;
private String author;
public Song(String title, String author){
this.title = title;
this.author = author;
}
public int getTitle(){ return title; }
public int getAuthor(){ return author; }
public void setTitle(String title){
this.title = title;
}
public void setAuthor(String author){
this.author = author;
}
}
35. Data classes
Java
class Song{
private String title;
private String author;
public Song(String title, String author){
this.title = title;
this.author = author;
}
public int getTitle(){ return title; }
public int getAuthor(){ return author; }
public void setTitle(String title){
this.title = title;
}
public void setAuthor(String author){
this.author = author;
}
}
Kotlin
data class Song(title: String, author: String)
36.
37. Interoperabile
Kotlin è 100% interoperabile,
questo significa che codice Java esistente può essere richiamato in Kotlin.
import java.text.SimpleDateFormat
import java.util.*
val dateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
val date = Date()
println(dateFormat.format(date))
38. Interoperabile
Anche da Java possiamo facilmente richiamare codice Kotlin.
Kotlin
// example.kt
package demo
class Foo
fun bar() {
}
Java
new demo.Foo();
demo.ExampleKt.bar();
si può utilizzare un’annotazione (@file:JvmName(“Esempio”)) per cambiare il nome del file
39. Conversione da Java a Kotlin
Android Studio converte automaticamente il codice scritto in Java in Kotlin.
Selezionando il codice Java scritto e cliccando cmd + alt + shift + k.
Oppure incollando del codice Java in un file Kotlin, Android Studio ci chiederà di
convertirlo.
40. Conversione da Java a Kotlin
public class Student {
public int age;
public final String name;
public final String surname;
public Student classmate;
public Student(int age, String name, String surname, Student classmate) {
this.age = age;
this.name = name;
this.surname = surname;
this.classmate = classmate;
}
}
41. Conversione da Java a Kotlin
public class Student {
public int age;
public final String name;
public final String surname;
public Student classmate;
public Student(int age, String name, String surname, Student classmate) {
this.age = age;
this.name = name;
this.surname = surname;
this.classmate = classmate;
}
}
CMD + SHIFT + ALT + K
42. Conversione da Java a Kotlin
class Student(var age: Int,
val name: String,
val surname: String,
var classmate: Student)
45. Nullable types
Niente può essere null in kotlin a meno che non lo si specifichi
var a : String = null // non compila
var corretto : String? = null // OK!
Safe call operator ?.
corretto?.length
questa chiamata ritorna corretto.length se corretto non è null, null altrimenti
46. Elvis operator
L’ elvis operator ?: permette di avere un’alternativa nel caso in cui un dato sia null
var messaggio : String? = null
//…
println(messaggio ?: "nessun messaggio")
47. Kotlin Android Extensions
Ogni sviluppatore android conosce la funzione findViewById().
Il plugin Kotlin Android Extension ci permette di accedere ad ogni elemento
(dichiarato nell’xml) senza l’uso di altro codice, ma semplicemente grazie ad un
specifico import.
48. Kotlin Android Extensions
// avremo il nostro layout: activity_main
import kotlinx.android.synthetic.main.activity_main.*
class MyActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// accediamo direttamente a textView senza nemmeno dichiararla
textView.setText("Hello world!")
}
}
49. Lambda e funzioni di ordine superiore
Una funzione lambda o funzione anonima è una funzione non dichiarata ma
passata immediatamente come espressione.
Per esempio:
max(strings, {a,b -> a.length < b.length})
max è una funzione di ordine superiore che prende come secondo parametro
un’altra funzione, in questo caso una lambda function
50. Lambda e funzioni di ordine superiore
Dichiarazione di una High Order Function
fun <T> max(collection: Collection<T>, less: (T, T) -> Boolean): T? {
var max: T? = null
for (it in collection)
if (max == null || less(max, it))
max = it
return max
}
51. Lambda e funzioni di ordine superiore
Button button= (Button) findViewById(R.id.buttonId);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// bla bla bla
}
});
52. Lambda e funzioni di ordine superiore
import kotlinx.android.synthetic.main.activity_main.*
class MyActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener{ println("Button clicked") }
}
}
53. Esempio funzionale : filter()
val numbers = arrayListOf(-42, 17, 13, -9, 12)
val nonNegative = numbers.filter { it -> it >= 0 }
it: è il nome implicito del singolo parametro
54. Esempio funzionale : apply()
La funzione apply() ritorna l’oggetto stesso e prende come argomento una funzione
che lo considera this.
Ad esempio:
// Java
private A updateA(A objA, B objB) {
objA.setC(objB.getC());
objA.setD(objB.getD());
return objA;
}
55. Esempio funzionale : apply()
La funzione apply() ritorna l’oggetto stesso e prende come argomento una funzione
che lo considera this.
Ad esempio:
// Kotlin
fun updateA(objA: A, objB: B): A = objA.apply { c = objB.c; d = objB.d }
56. Delegate - Lazy
lazy()
É una funzione che prende come argomento una lambda che viene eseguita solo
alla prima chiamata della get(), alle chiamate successive ritornerá il risultato
“ricordato”.
57. Delegate - Lazy
val genericString: String by lazy{
println("init")
"genericString"
}
fun main(args: Array<String>) {
println(genericString)
println(genericString)
}
// Output:
// Init
// genericString
// genericString
58. Delegate - Observable
Delegates.observable()
Prende due argomenti, il valore iniziale e un handler.
L’handler viene chiamato ogni volta che effettuiamo un assegnamento e ha 3
parametri:
l’attributo, il vecchio valore e il nuovo valore.
59. Delegate - Observable
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("<undefined>") {
prop, old, new -> println("$old -> $new")
}
}
fun main(args: Array<String>) {
val user = User()
user.name = "first"
user.name = "second"
println(user.name)
}
// Output:
// <undefined> -> first
// first -> second
// second
60. Chi ha le migliori prestazioni
fra Kotlin e Java?
61. JVM & Performance
Il compilatore Kotlin emette JVM byte-code, grazie a questo Kotlin puó chiamare Java e vice
versa (interoperabile 100%).
È possibile vedere il bytecode generato, in tempo reale:
Tools > Kotlin > Show bytecode.
62. JVM & Performance
Il JVM byte-code prodotto da Kotlin e’ equivalente a quello di Java per cui le prestazioni sono le
stesse, non abbiamo un vincitore in questo senso!
63. JVM & Performance
Il JVM byte-code prodotto da Kotlin e’ equivalente a quello di Java per cui le prestazioni sono le
stesse, non abbiamo un vincitore in questo senso!
La cosa che fa davvero differenza sono gli algoritmi e le strutture dati usate dallo sviluppatore.
64. JVM & Performance
Il JVM byte-code prodotto da Kotlin e’ equivalente a quello di Java per cui le prestazioni sono le
stesse, non abbiamo un vincitore in questo senso!
La cosa che fa davvero differenza sono gli algoritmi e le strutture dati usate dallo sviluppatore.
In questo Kotlin ci aiuta: prevede alcuni built-in patterns, come le Data Classes che sono un
ottimo esempio dell’ Immutable Object pattern
66. Installazione
Kotlin può essere utilizzato dopo pochi semplici passaggi:
● “Android Studio” -> “Preferences”
● “Plugins”, cerchiamo Kotlin
● Installiamo Kotlin e riavviamo Android Studio
● Creiamo un nuovo file Kotlin (i.e. Kotlin class)
dal menu “Tools” -> “Kotlin” -> “Configure Kotlin in Project”
67. Installazione
In questo modo Gradle sarà configurato per utilizzare Kotlin.
Volendo utilizzare anche Kotlin Android Extensions basterà inserire nel nostro
modulo Gradle:
apply plugin: 'kotlin-android-extensions'
69. Retrofit
“Is a type-safe HTTP client for Android and Java”
Trasforma la nostra HTTP API in interfaccia.
70. Retrofit
“Is a type-safe HTTP client for Android and Java”
Trasforma la nostra HTTP API in interfaccia.
interface ApiClient {
//baseurl = http://api.giphy.com/
@GET("v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=xmas")
fun getImgResponse(): Call<ImgResponse>
}
71. Retrofit
Ci serviranno solo alcuni dei campi del
Json di risposta alla chiamata a giphy.
Utilizzeremo quindi le data classes.
data class ImgResponse (val data: ImgUrl)
data class ImgUrl (val image_url: String)