Kotlin per Android: basi della sintassi e funzionalità

Autore: IT Sectr Pubblicato: 2026-02-10 Tempo di lettura: 8 min

Kotlin è un linguaggio di programmazione tipizzato staticamente di JetBrains, che funziona su JVM ed è ufficialmente supportato da Google per lo sviluppo Android dal 2017. Kotlin è completamente compatibile con Java, ha una sintassi concisa e null safety integrata. Kotlin Documentation — guida completa al linguaggio e alla libreria standard.

Punti Chiave

  • Kotlin — linguaggio JVM tipizzato staticamente di JetBrains con sintassi concisa e null safety
  • Null safety — il compilatore distingue tipi nullable (String?) e non-null (String), eliminando NullPointerException
  • Data class — generazione automatica di equals, hashCode, toString, copy e componentN
  • Extension functions — aggiunta di metodi a classi esistenti senza ereditarietà tramite chiamate statiche
  • Coroutine — programmazione asincrona con stile sequenziale tramite funzioni suspend senza bloccare i thread

Cos'è Kotlin?

Kotlin è un linguaggio di programmazione tipizzato staticamente creato da JetBrains (sviluppatore di IntelliJ IDEA) e rilasciato nel 2016 sotto licenza Apache 2.0. Kotlin compila in bytecode JVM, JavaScript e codice nativo (tramite Kotlin/Native). I suoi principali ambiti di applicazione sono lo sviluppo Android, le applicazioni lato server e i progetti multipiattaforma.

Google ha annunciato Kotlin come linguaggio ufficiale per lo sviluppo Android al Google I/O 2017. Secondo Google (Android Developer Blog, 2026), oltre l'85% dei nuovi progetti su Google Play utilizza Kotlin. Il linguaggio è anche attivamente utilizzato nello sviluppo server (Spring Boot, Ktor) e nei progetti multipiattaforma (Kotlin Multiplatform Mobile).

Kotlin è completamente compatibile con Java — puoi chiamare codice Java da Kotlin e viceversa nello stesso progetto. Gli strumenti di build (Gradle, Maven) supportano entrambi i linguaggi, consentendo una migrazione graduale da Java a Kotlin senza tempi di inattività nello sviluppo.

Perché Kotlin è più popolare di Java per Android

Le ragioni principali: concisione — Kotlin richiede in media il 40% in meno di righe di codice rispetto a Java per lo stesso compito. Null safety — il compilatore proibisce l'uso di tipi nullable senza controllo. Capacità funzionali — funzioni di ordine superiore, lambda, funzioni di estensione e coroutine rendono il codice più espressivo e sicuro.

Basi della sintassi

La sintassi di base di Kotlin combina concisione e chiarezza. Le variabili vengono dichiarate con val (immutabile) e var (mutabile). Il compilatore usa l'inferenza dei tipi, ma la dichiarazione esplicita del tipo è supportata. Le funzioni vengono dichiarate con la parola chiave fun.

kotlin
package com.example.intro

// Costanti e variabili
val appName: String = "KotlinApp"  // immutabile
var version = 1.0  // mutabile, tipo inferito

// Funzione con expression body
fun sum(a: Int, b: Int) = a + b

// String templates
fun greet(name: String) = "Ciao, $name! Versione ${appName}_$version"

// Default and named arguments
fun createUser(
    name: String,
    age: Int = 18,
    email: String? = null
)

L'espressione when sostituisce switch in Java ed è più flessibile: supporta controlli di tipo, intervalli, condizioni e rami senza break. Il compilatore verifica la copertura esaustiva per classi enum e sealed. Gli smart cast convertono automaticamente i tipi dopo un controllo is, eliminando cast espliciti.

kotlin
fun analyzeValue(value: Any) = when (value) {
    is String -> "Stringa di lunghezza ${value.length}"  // smart cast
    is Int -> "Numero intero: $value"
    in 1..10 -> "Numero nell'intervallo 1-10"
    else -> "Tipo sconosciuto"
}

Null safety e operatori Elvis

Null safety è una caratteristica fondamentale di Kotlin che elimina NullPointerException in fase di compilazione. In Kotlin, i tipi non possono essere null per impostazione predefinita. Per consentire null, aggiungi ? al tipo: String?. Il compilatore richiede un controllo esplicito di ogni valore nullable.

kotlin
// Tipi nullable e non-null
val nonNull: String = "Sempre non null"
val nullable: String? = null  // consentito

// Safe call — esegue solo se non null
val length: Int? = nullable?.length

// Operatore Elvis — valore predefinito
val text: String = nullable ?: "Default text"

// Let — esegui blocco con valore non-null
nullable?.let { value ->
    println("Valore: $value")
}

L'operatore safe call (?.) restituisce null se l'oggetto prima dell'operatore è null e chiama il metodo/proprietà altrimenti. L'operatore Elvis (?:) fornisce un valore predefinito se la parte sinistra è null. L'asserzione not-null (!!) lancia NullPointerException se il valore è null — usala solo quando sei sicuro al 100% che il valore esista.

Tipi platform — tipi Java dal codice Java chiamato che Kotlin non può marcare come nullable o non-null. Il tipo viene visualizzato come String! (con punto esclamativo). Lo sviluppatore è responsabile della null safety quando lavora con codice Java.

Data class e destrutturazione

Le data class in Kotlin generano automaticamente equals(), hashCode(), toString(), copy() e componentN(). Questo elimina il boilerplate dei modelli Java (POJO) e rende il codice più pulito. Dichiarare una data class richiede una riga invece di 20-30 in Java.

kotlin
data class User(
    val id: Long,
    val name: String,
    val email: String,
    val age: Int? = null
)

// Utilizzo
val user = User(1, "Anna", "anna@example.com")
val updatedUser = user.copy(age = 25)

// Destrutturazione
val (id, name) = user
println("Utente #$id: $name")

La destrutturazione permette di scomporre una data class in variabili in una singola riga. Questo è comodo quando si lavora con coppie, triple e altri valori compositi. La destrutturazione è supportata per data class, collezioni standard (List, Map) e qualsiasi classe con operator fun componentN().

Funzioni di estensione

Le funzioni di estensione sono un meccanismo di Kotlin per aggiungere nuovi metodi a classi esistenti senza ereditarietà. Le estensioni vengono compilate in metodi statici con un parametro receiver, quindi l'ereditarietà non è richiesta e il dispatch virtuale non è supportato.

kotlin
// Funzione di estensione per String
fun String.isEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

// Proprietà di estensione
val String.isPhoneNumber: Boolean
    get() = this.matches(Regex("^\\+?[\\d-]{10,15}$"))

// Estensione generica per collezioni
fun List<Int>.sumOfEvens(): Int {
    return this.filter { it % 2 == 0 }.sum()
}

// Utilizzo
println("test@mail.com".isEmail())  // true

Le estensioni sono ampiamente utilizzate nell'Android SDK e nelle librerie. Ad esempio, le Activity extensions in Android KTX sono funzioni di estensione per Activity, Fragment, View e altre classi. Le estensioni possono essere dichiarate come funzioni di livello superiore in un file o come estensioni membro di una classe.

Coroutine per la programmazione asincrona

Le coroutine sono un meccanismo di programmazione asincrona in Kotlin che permette di scrivere codice non bloccante in stile sequenziale. Una coroutine sospende l'esecuzione su una funzione suspend senza bloccare il thread e riprende dopo il completamento dell'operazione. È un'alternativa alle catene di callback RxJava e AsyncTask.

kotlin
import kotlinx.coroutines.*

// Funzione suspend — può sospendersi
suspend fun fetchUserData(userId: Int): User {
    // delay — funzione suspend, non blocca il thread
    delay(500)
    return User(userId, "User $userId", "user@example.com")
}

// Avvia in coroutine
fun loadData() {
    CoroutineScope(Dispatchers.Main).launch {
        val user = fetchUserData(1)  // pausa qui
        updateUI(user)  // continua sul thread Main
    }
}

I Dispatchers determinano il pool di thread per una coroutine: Dispatchers.Main (thread UI), Dispatchers.IO (operazioni di rete/disco), Dispatchers.Default (attività intensive per CPU). La concorrenza strutturata garantisce che una coroutine non rimanga attiva dopo il completamento dello scope — questo previene perdite di memoria.

kotlin
// Esecuzione parallela tramite async/await
suspend fun loadDashboard(): Dashboard = coroutineScope {
    val user = async { fetchUserData(1) }
    val orders = async { fetchOrders(1) }
    val stats = async { fetchStats() }
    
    Dashboard(user.await(), orders.await(), stats.await())
}

Kotlin vs Java: confronto

La scelta tra Kotlin e Java per un nuovo progetto Android è una decisione architetturale fondamentale. Kotlin offre una sintassi più moderna e meccanismi di sicurezza integrati, mentre Java ha un pool più ampio di sviluppatori e librerie mature.

CaratteristicaKotlinJava
Null safetyIntegrata (nullable/non-null)Non integrata (annotazioni @Nullable)
Volume di codice−40% rispetto a JavaBoilerplate (getters/setters)
Data classdata class (una riga)POJO con Lombok o manuale
AsincroniaCoroutine (suspend/await)CompletableFuture, RxJava
Funzioni di estensioneIntegrateSolo tramite classi utility
Smart castDopo controllo isCast esplicito (Type) obj
Compatibilità all'indietro100% con Java

Prestazioni di Kotlin e Java sono comparabili — entrambi compilano in bytecode JVM. Kotlin a volte aggiunge un micro-overhead per coroutine e inlining, ma è trascurabile per le applicazioni mobili. Google e JetBrains investono attivamente in Kotlin: Kotlin Multiplatform, Kotlin/Wasm e miglioramenti delle prestazioni del compilatore K2.

Domande Frequenti

In cosa Kotlin è diverso da Java?

Kotlin è 40% più corto di Java — meno boilerplate. Kotlin aggiunge null safety, data class, funzioni di estensione, coroutine, smart cast, espressioni when. Compatibilità totale con Java: entrambi i linguaggi funzionano su JVM e possono essere usati nello stesso progetto senza conflitti.

Come funziona null safety in Kotlin?

I tipi sono non-null per impostazione predefinita. Per nullable usa ?: String?. Il compilatore proibisce l'accesso diretto a valori nullable. Safe call (?.) restituisce null su ricevitore null. Operatore Elvis (?:) imposta un valore predefinito. !! — estrazione forzata con possibile eccezione.

Cosa sono le coroutine in Kotlin?

Le coroutine sono thread leggeri che permettono di scrivere codice asincrono in modo sequenziale. Le funzioni suspend si mettono in pausa senza bloccare il thread. launch e async avviano coroutine in CoroutineScope. Dispatchers.IO per richieste di rete, Dispatchers.Main per aggiornamenti UI.

Cosa sono le data class in Kotlin?

data class genera automaticamente equals(), hashCode(), toString(), copy() e componentN(). Esempio: data class User(val name: String, val age: Int). Destrutturazione tramite val (name, age) = user. Simile a record in Java 14+, ma con il metodo aggiuntivo copy().

Come funzionano le funzioni di estensione?

Le funzioni di estensione aggiungono metodi a classi esistenti: fun String.isEmail(): Boolean. Il compilatore le sostituisce con chiamate statiche con un parametro receiver. Non è richiesta ereditarietà. Le estensioni sono ampiamente utilizzate in Android KTX: view.showToast(), activity.viewModels().

Riepilogo

  • Kotlin — linguaggio JVM tipizzato staticamente di JetBrains, linguaggio ufficiale di Android dal 2017
  • Null safety — tipi nullable/non-null, safe call (?.), elvis (??), blocchi let per lavoro sicuro con nullable
  • Data class — generazione automatica di equals, hashCode, toString, copy e destrutturazione
  • Funzioni di estensione — aggiunta di metodi a qualsiasi classe senza ereditarietà, compilate in chiamate statiche
  • Coroutine — codice asincrono in stile sequenziale con funzioni suspend, launch/async e Dispatchers
  • Confronto con Java − −40% codice, null safety, smart cast, espressioni when e 100% compatibilità con Java
  • Kotlin Multiplatform — Kotlin è usato non solo per Android ma anche per iOS (KMM) e server (Ktor, Spring)

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche