O que é Nullable em Kotlin?

Em Kotlin, todo tipo é não-nulo por padrão. Se você declara uma variável como String, ela não pode receber null. Para permitir valores nulos, você precisa adicionar ? ao tipo, criando um tipo nullable como String?.

Essa é uma das maiores sacadas do Kotlin: o famoso NullPointerException é praticamente eliminado em tempo de compilação.

Declarando tipos nullable

var nome: String = "Karina"
// nome = null  // Erro de compilação!

var apelido: String? = "Kah"
apelido = null  // Tudo certo!

Operador de chamada segura ?.

O operador ?. só executa a operação se o valor não for nulo:

val cidade: String? = "São Paulo"
println(cidade?.length)    // 9

val estado: String? = null
println(estado?.length)    // null (não dá erro!)

Operador Elvis ?:

O operador Elvis fornece um valor padrão quando o original é nulo:

val nome: String? = null
val exibicao = nome ?: "Anônimo"
println(exibicao) // Anônimo

Combina muito bem com o operador ?.:

fun tamanhoDoNome(nome: String?): Int {
    return nome?.length ?: 0
}

println(tamanhoDoNome("Fernanda")) // 8
println(tamanhoDoNome(null))       // 0

Operador de asserção !!

O !! força a conversão para não-nulo, mas lança exceção se o valor for null:

val valor: String? = "Kotlin"
println(valor!!.length) // 6

val nulo: String? = null
// println(nulo!!.length) // NullPointerException!

Use !! com muito cuidado — só quando você tem certeza absoluta de que o valor não é nulo.

Smart cast com if

O Kotlin faz smart cast automaticamente após verificações de null:

fun imprimir(texto: String?) {
    if (texto != null) {
        // Aqui o compilador já sabe que texto não é null
        println(texto.uppercase())
    }
}

Boas práticas

  • Prefira ?. e ?: em vez de !!
  • Use let para trabalhar com nullable: valor?.let { println(it) }
  • Evite tipos nullable quando possível — menos ?, menos problemas