Kotlin: null safety, safe cast e operatore Elvis
In Kotlin la null safety è una procedura per eliminare il rischio di avere nel codice referenze nulle. In caso contrario il compilatore genera un’eccezione di tipo NullPointerException senza permettere bloccando qualsiasi operazione. Eccezioni di questo tipo possono essere generate:
- quando si accede o modifica un campo di un oggetto null,
- quando si invocano metodi su un oggetto non inizializzato,
- quando si passano parametri nulli ad un metodo,
- quando si chiama esplicitamente la throw NullPointerException(),
- quando si chiama il metodo toString() ad un oggetto nullo,
- quando si confronta il blocco delle proprietà degli oggetti senza verificare l’uguaglianza nulla,
- quando si prende la lunghezza di null come se fosse un array,
- quando si utilizza synchronized su un oggetto nullo,
- quando si hanno istruzioni concatenate come più chiamate di metodo in una singola istruzione,
- quando si accede o modifica gli slot di null come se fosse un array,
- quando un operatore non inizializzato disponibile in un costruttore è passato e ha utilizzato un altro posto,
- quando si utilizza un codice esterno scritto in Java.
Indipendentemente dalla null safety esistono comunque delle best practice per evitare di cadere nella generazione di una NullPointerException, in particolare:
- evitare il confronto di stringhe con letterali
- evitare di utilizzare null come valore di ritorno di un metodo
- effettuare continui controlli sulla corretta valorizzazione degli argomenti passati alle funzioni e metodi
- utilizzare String.valueOf () invece di toString ()
- utilizzare il più possibile tipi di dati primitivi
- evitare le chiamate di metodo concatenate
- utilizzare l’operatore ternario
Nullable Types
In Kotlin, il sistema di tipi si differenzia tra quelli che supportano una referenza ad un valore null (nullable types) e quelli no (non-nullable types). Per rendere un tipo base nullable è necessario aggiungere la keyword ? in fase di dichiarazione. Data una variabile value , la sintassi per poterle attribuire il valore null dato un tipo Type non-nullable è:
var value : Type? = null
Ovviamente se invece usassimo var value : Type = null otterremo un errore di compilazione in quanto se Type? è nullable, Type è non-nullable. Ricordiamo inoltre che l’accesso alle proprietà di variabili nullable deve avvenire utilizzando il carattere ? o !!. Nel primo caso le proprietà torneranno null nel caso in cui la variabile è null, mentre nel secondo verrà generata un’eccezione di tipo NullPointerException. Se non si usano nessuno dei due caratteri si otterrà un errore di compilazione. Esempio di utilizzo è quindi:
var str : String? = null
var len1 : Int? = str?.length
var len2 : Int? = str!!.length
Cast
Kotlin, grazie alla null safety ci mette nelle condizioni di non accedere a metodi di una variabile di tipo nullable. Pertanto per utilizzare tali metodi (ad esempio la proprietà length di una stringa) è necessario applicare quello che prende il nome di smart cast ovvero:
var string : String? = "Hello!"
if(string != null) {
print(string.length)
}
Lo smart cast può essere utilizzato anche tramite la keyword is (e la sua negata) per sfruttare la type inference del Kotlin. Pertanto, ad esempio:
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
in questo caso è possibile utilizzare le proprietà della variabile x in modo diverso a seconda del suo tipo. Ovviamente il compilatore controllerà che non ci sono variazioni di tipo della variabile x tra il check del tipo (che garantisce il cast via type inference) ed il suo utilizzo. Per maggiori informazioni visitate il sito https://kotlinlang.org/docs/typecasts.html . A volte però non è possibile castare una variabile portando alla generazione di un’eccezione. In questo caso si parla di unsafe cast e si manifesta utilizzando l’operatore as il quale permette di castare una determinata variabile ad un certo tipo. Il problema si manifesta quando la variabile da castare è una variabile di tipo nullable ad una non-nullable portando alla generazione di un’eccezione di tipo TypeCastException. Proprio per questo in Kotlin è stato sviluppato l’operatore di as? il quale torna null nel caso in cui il cast non è possibile, senza generare nessuna eccezione. Questo tipo di cast si definisce safe cast.
Operatore Elvis
L’operatore Elvis ?: è utilizzato per verificare la null safety di una variabile, ovvero se questa è nulla oppure no. Date due stringhe nullable str1 ed str2, un esempio di applicazione dell’operatore Elvis può essere:
var str1 : String? = null
var str2 : String? = "not null string"
var len1 : Int = str1 ?.length ?: -1
var len2 : Int = str2 ?.length ?: -1
In questo caso, Kotlin prova a calcolare la lunghezza delle due stringhe e nel caso si generi un’eccezione dovuta alla presenza di una variabile null, allora esegue la parte di codice riportata a destra dell’operatore Elvis. In particolare nel caso di str1, len1 varrà -1 e nessuna eccezione verrà generata. Per maggiori informazioni si faccia riferimento a https://kotlinlang.org/docs/null-safety.html .
Commenti recenti