Kotlin — Cheat Sheet

Tag: kotlin, jvm, android, coroutines, null-safety, oop

Livello: intermedio

TL;DR: Linguaggio a tipizzazione statica per la JVM, conciso e sicuro, focalizzato sull'eliminazione delle NullPointerException e sull'interoperabilità completa con Java.

Concetti chiave

Null safety nativa: il type system distingue rigorosamente i tipi nullable (Type?) da quelli non-nullable (Type).

Immutabilità di default: val definisce variabili in sola lettura, var definisce variabili mutabili.

Smart casts: il compilatore effettua il cast automatico del tipo subito dopo averlo verificato con l'operatore is.

Data classes: generano in automatico equals(), hashCode(), toString() e copy() per i modelli di dati senza boilerplate.

Extension functions: permettono di aggiungere metodi a classi esistenti o di terze parti senza ricorrere all'ereditarietà.

Coroutines: pattern per la programmazione asincrona leggera e la gestione della concorrenza senza bloccare i thread primari.

Classi e metodi sono final di default; richiedono l'uso esplicito del modificatore open per l'ereditarietà.

Interoperabilità bidirezionale totale: è possibile chiamare codice Java da Kotlin e viceversa senza alcun overhead.

Domande tipiche e risposte pronte

Q: Qual è la differenza tra l'operatore safe call ?. e l'operatore Elvis ?:?R: Il safe call ?. valuta la catena ed esegue l'operazione solo se l'oggetto non è null, altrimenti restituisce null in sicurezza. L'operatore Elvis ?: fornisce invece un valore di fallback esplicito se l'espressione alla sua sinistra risulta null.

Q: A cosa serve il modificatore inline in Kotlin?R: Serve a ottimizzare le funzioni di ordine superiore. Il compilatore copia il bytecode della funzione inline e delle lambda passate direttamente nel punto in cui viene chiamata, evitando l'allocazione di nuovi oggetti in memoria.

Q: Come si dichiara un pattern Singleton in Kotlin?R: Utilizzo direttamente la keyword object al posto di class. Il linguaggio gestisce automaticamente la singola istanza in modo thread-safe.

Insidie e errori comuni

Abusare dell'operatore !! (not-null assertion) per forzare il bypass del compilatore, reintroducendo a runtime le eccezioni NullPointerException.

Dimenticare di gestire il lifecycle delle coroutines e non cancellare i Job attivi quando i componenti UI vengono distrutti, portando a gravi memory leak.

Esporre collezioni mutabili (MutableList) nelle interfacce pubbliche delle classi invece di isolarle tramite il tipo in sola lettura (List).

Snippet e comandi

// Data class standard
data class User(val id: String, val email: String)

// Null safety: Safe call e operatore Elvis combinati
val usernameLength = user?.name?.length ?: 0

// Extension function per la classe String
fun String.isValidEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

// Dichiarazione di un Singleton
object DatabaseClient {
    fun connect() { /* ... */ }
}

// Esempio base di Coroutine con cambio di context
lifecycleScope.launch {
    val data = withContext(Dispatchers.IO) {
        // Esecuzione di task network o database sincroni (background)
        fetchDataFromApi()
    }
    // Aggiornamento della UI in modo sicuro sul main thread
    showData(data)
}
Jarvis Interviews
Jarvis