O que e Enum em Kotlin?
Um enum class em Kotlin define um conjunto fixo de constantes. Cada constante é uma instancia única da classe enum, representando um valor possível dentro de um grupo fechado. E ideal pra representar opções predefinidas como dias da semana, estados, categorias, etc.
Pense num semaforo: ele só pode estar vermelho, amarelo ou verde. Nao existe um quarto estado. Um enum faz exatamente isso no código – define todas as opções possiveis e garante que nenhum valor inválido seja usado. Isso traz seguranca de tipos que simples constantes String ou Int não oferecem.
Enums em Kotlin vao além de simples listas de constantes. Eles podem ter propriedades, métodos, implementar interfaces e até conter lógica complexa. Combinados com a expressao when, formam uma dupla poderosa para modelar dominios de negócio.
Sintaxe básica
enum class Cor {
VERMELHO, VERDE, AZUL, AMARELO
}
fun main() {
val minhaCor = Cor.VERDE
println(minhaCor) // VERDE
println(minhaCor.name) // VERDE
println(minhaCor.ordinal) // 1
}
Cada constante tem name (o nome como String) e ordinal (a posicao, comecando do zero).
Enum com propriedades
enum class Estado(val sigla: String, val regiao: String) {
SAO_PAULO("SP", "Sudeste"),
RIO_DE_JANEIRO("RJ", "Sudeste"),
BAHIA("BA", "Nordeste"),
PARANA("PR", "Sul")
}
fun main() {
val estado = Estado.BAHIA
println("${estado.name}: ${estado.sigla} - ${estado.regiao}")
// BAHIA: BA - Nordeste
}
Enum com métodos
enum class Operacao {
SOMA {
override fun calcular(a: Double, b: Double) = a + b
},
SUBTRACAO {
override fun calcular(a: Double, b: Double) = a - b
},
MULTIPLICACAO {
override fun calcular(a: Double, b: Double) = a * b
};
abstract fun calcular(a: Double, b: Double): Double
}
fun main() {
println(Operacao.SOMA.calcular(10.0, 3.0)) // 13.0
println(Operacao.MULTIPLICACAO.calcular(10.0, 3.0)) // 30.0
}
Usando com when
Enum combina perfeitamente com when:
enum class StatusPedido { PENDENTE, PROCESSANDO, ENVIADO, ENTREGUE }
fun mensagem(status: StatusPedido): String = when (status) {
StatusPedido.PENDENTE -> "Aguardando confirmacao"
StatusPedido.PROCESSANDO -> "Preparando seu pedido"
StatusPedido.ENVIADO -> "Pedido a caminho!"
StatusPedido.ENTREGUE -> "Pedido entregue com sucesso"
}
funções utilitarias
// Listar todos os valores
Cor.entries.forEach { println(it) }
// Converter de String
val cor = Cor.valueOf("AZUL")
println(cor) // AZUL
Enum implementando interface
Enums podem implementar interfaces, o que permite usar polimorfismo com conjuntos fixos de valores:
interface Descritivel {
fun descricao(): String
}
enum class Prioridade : Descritivel {
BAIXA {
override fun descricao() = "Pode esperar, sem urgencia"
},
MEDIA {
override fun descricao() = "Resolver em breve"
},
ALTA {
override fun descricao() = "Resolver o mais rapido possivel"
},
CRITICA {
override fun descricao() = "Parar tudo e resolver agora"
}
}
fun main() {
Prioridade.entries.forEach { p ->
println("${p.name}: ${p.descricao()}")
}
}
Enum com companion object para busca customizada
Muitas vezes você precisa encontrar um enum a partir de um valor que não e o name. Usar um companion object resolve isso:
enum class Moeda(val codigo: String, val simbolo: String) {
REAL("BRL", "R$"),
DOLAR("USD", "$"),
EURO("EUR", "E");
companion object {
fun porCodigo(codigo: String): Moeda? =
entries.find { it.codigo == codigo }
}
}
fun main() {
val moeda = Moeda.porCodigo("BRL")
println("${moeda?.name} - ${moeda?.simbolo}") // REAL - R$
val desconhecida = Moeda.porCodigo("GBP")
println(desconhecida) // null
}
Casos de Uso no Mundo Real
- Status de pedidos em e-commerce: representar estados como PENDENTE, PAGO, ENVIADO, ENTREGUE e CANCELADO. Cada status pode ter propriedades como cor de exibicao e mensagem para o cliente.
- Permissoes de usuário: definir niveis de acesso como ADMIN, EDITOR e LEITOR, cada um com um conjunto de permissoes associadas.
- Dias da semana e meses: usar enums para representar periodos de tempo evita erros de digitacao e garante que apenas valores validos sejam utilizados.
- Tipos de pagamento: CARTAO_CREDITO, CARTAO_DEBITO, PIX, BOLETO – cada tipo com suas regras de processamento definidas como métodos abstratos no enum.
- configuração de ambientes: DESENVOLVIMENTO, HOMOLOGACAO e PRODUCAO, cada um com URLs e credenciais diferentes.
Boas Praticas
- Use enum sempre que tiver um conjunto fixo e conhecido de opções. Evite usar Strings ou Ints magicos para representar estados.
- Combine enum com when exaustivo. Como o compilador sabe todos os valores possiveis, ele avisa se você esquecer algum caso.
- Adicione propriedades ao enum em vez de usar
whenpara mapear cada constante a um valor. E mais fácil de manter. - Considere sealed classes quando os valores precisam carregar dados diferentes entre si. Enums sao ideais quando todos os valores tem a mesma estrutura.
- Use
entriesem vez devalues()a partir do Kotlin 1.9, poisentriesretorna uma lista imutavel e tem melhor performance.
Erros Comuns
- Usar
valueOf()sem tratar exceção:valueOf("valor_invalido")lancaIllegalArgumentException. Sempre trate com try-catch ou crie uma função auxiliar que retorne null. - Comparar enum por ordinal: nunca use
ordinalpara lógica de negócio. Se alguem reordenar as constantes, o código quebra silenciosamente. - Esquecer o ponto-e-virgula: quando um enum tem membros (métodos ou propriedades) além das constantes, e obrigatório colocar
;apos a ultima constante. - Tentar criar instancias em runtime: enums tem um conjunto fixo de instancias. Voce não pode criar
Cor("ROXO")em tempo de execução. Se precisar disso, considere uma sealed class.
Perguntas Frequentes
Qual a diferenca entre enum e sealed class? Enums definem um conjunto fixo de instancias unicas, todas com a mesma estrutura. Sealed classes definem um conjunto fixo de tipos, mas cada tipo pode ter propriedades e construtores diferentes. Use enum para valores simples e sealed class para hierarquias mais complexas.
Posso usar enum em destructuring?
Nao diretamente, pois enums não geram funções componentN(). Mas você pode implementa-las manualmente ou usar as propriedades do enum diretamente.
Enum consome muita memória?
Nao. Cada constante e uma instancia única criada quando a classe e carregada. Independentemente de quantas vezes você referência Cor.VERDE, e sempre o mesmo objeto na memória.
Posso serializar enums com Kotlin Serialization?
Sim. Basta anotar o enum com @Serializable. Por padrão, a serialização usa o name da constante. Voce pode customizar com @SerialName em cada constante.
Enums sao simples, seguros e expressivos. Use sempre que tiver um conjunto fixo de opções no seu dominio.