ProgrammazioneSviluppatore Android

Come funziona l'operatore di accesso sicuro (safe call operator '?.') in Kotlin e quando applicarlo per lavorare con tipi nullable?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

L'operatore di accesso sicuro '?.' è uno degli strumenti chiave per gestire i valori null in Kotlin ed è stato introdotto come sviluppo delle idee di un linguaggio mirato a migliorare la sicurezza e la comodità di lavoro con valori potenzialmente assenti.

Storia della questione: In Java, i valori null diventano spesso fonte di errori (NullPointerException). Kotlin ha introdotto un sistema di tipi rigoroso con una distinzione evidente tra variabili nullable e not-nullable, accompagnato da strumenti per il loro utilizzo conveniente.

Problema: Come evitare NullPointerException quando si lavora con oggetti che possono essere null, senza compromettere la leggibilità e la concisione del codice?

Soluzione: L'operatore '?.' consente di accedere delicatamente alle proprietà e ai metodi delle variabili nullable: se l'oggetto non è null, viene eseguita la chiamata, se è null — viene restituito null (o la logica necessaria prosegue).

Esempio di codice:

val user: User? = getUser() val name = user?.name // se user != null, restituirà user.name, altrimenti null user?.printInfo() // se user != null, verrà chiamato printInfo()

Caratteristiche chiave:

  • Consente di evitare controlli espliciti if (object != null) { ... }
  • È un'alternativa compatta e conveniente a catene di controlli annidati
  • Può essere utilizzato insieme a let e all'operatore Elvis per gestire il caso null

Domande trabocchetto.

Può l'operatore di accesso sicuro '?.' essere utilizzato a sinistra della assegnazione?

No. L'operatore '?.' non può essere utilizzato per impostare in modo sicuro il valore di una proprietà o di una variabile; viene utilizzato solo per l'accesso o la chiamata. La seguente istruzione è scorretta:

user?.name = "Alex" // Errore di compilazione

L'assegnazione delle proprietà può essere effettuata in modo sicuro tramite un controllo esplicito:

user?.let { it.name = "Alex" }

Cosa restituisce una catena di operatori di accesso sicuro al primo incontro con null?

Non appena uno degli elementi della catena '?.' è uguale a null, il risultato dell'espressione diventa null, e ulteriori chiamate sicure non vengono eseguite.

Esempio:

user?.address?.zipCode // se user o address == null, il risultato è null

È possibile utilizzare l'accesso sicuro '?.' con le funzioni che restituiscono Unit?

Sì, la chiamata avverrà comunque solo se l'oggetto non è null, altrimenti restituirà null invece di Unit se l'oggetto è null.

Esempio:

user?.clearData() // se user == null, non succede nulla

Errori tipici e anti-pattern

  • Usare '!!' dopo '?.' — si perde il significato della chiamata sicura, potrebbe portare a NullPointerException.
  • Costruire catene lunghe di '?.' senza gestire il caso null in uscita — il risultato potrebbe essere scomodo per ulteriori elaborazioni senza verifiche aggiuntive.

Esempio dalla vita reale

Caso negativo

Lo sviluppatore usa '!!' dove l'oggetto potrebbe essere null, dopo una lunga catena di accessi sicuri:

val country = user?.address?.city?.country!!

Vantaggi:

  • Risulta conciso.

Svantaggi:

  • Ad ogni null nella catena l'applicazione si bloccherà con NullPointerException.

Caso positivo

Si utilizza l'accesso sicuro insieme all'operatore Elvis per restituire un valore predefinito:

val country = user?.address?.city?.country ?: "Unknown"

Vantaggi:

  • Protezione dagli errori, comportamento prevedibile, leggibilità.

Svantaggi:

  • Potrebbe essere difficile diagnosticare, in quale punto della catena sia comparso null senza log aggiuntive.