Public get private set em Kotlin: armadilhas e soluções

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Public get, private set em Kotlin: como não pisar na bola (e o que fazer se já pisou)

\n\n

Olá, colega! Se você já pesquisou "Kotlin public get private set var" no Google, não está sozinho. Essa consulta é um verdadeiro sucesso no Stack Overflow, e milhares de desenvolvedores (incluindo eu, no passado) bateram a cabeça no teclado tentando entender por que seu código não funcionava.

\n\n

Parece simples, não? Quero que a propriedade seja acessível a todos (public get), mas apenas a própria classe possa modificá-la (private set). Em Java, era rotina: declarar um campo private, escrever um getter e um setter, e tornar o setter privado. Em Kotlin, tudo deveria ser mais fácil, mas...

\n\n

Spoiler: a sintaxe existe, mas nem sempre funciona como você espera. Neste artigo, vamos analisar os principais erros que até desenvolvedores experientes cometem e mostrar como evitá-los. Vamos lá!

\n\n

Anatomia de uma propriedade: var, val, get e set

\n\n

Para começar, uma rápida introdução. Em Kotlin, propriedades (properties) não são apenas campos. São elementos completos que podem conter getters e setters. Aqui está a estrutura básica:

\n\n
var nome_da_propriedade: Tipo = valor_padrao\n    get() = field\n    set(value) { field = value }
\n\n

Se você usa var, o Kotlin gera automaticamente um getter e um setter. Mas você pode substituir o comportamento deles. E também pode alterar a visibilidade deles (visibility modifiers: public, private, internal, protected).

\n\n

E é aqui que a coisa fica interessante. Para tornar o getter público e o setter privado, você precisa escrever:

\n\n
var name: String = "default"\n    private set
\n\n

Só isso? Quase. Mas existem nuances que quebram esse mecanismo.

\n\n

Erro nº 1: Esquecer o construtor

\n\n

O problema mais comum é tentar declarar public get private set var no construtor da classe. Por exemplo:

\n\n
// ❌ Erro: não é permitido\nclass User(public get private set var name: String)
\n\n

O Kotlin emitirá um erro de compilação. Por quê? Porque os parâmetros do construtor não são propriedades. São apenas parâmetros. Se você quer que uma propriedade tenha a visibilidade do setter alterada, ela deve ser declarada no corpo da classe.

\n\n

Como fazer corretamente:

\n\n
class User(name: String) {\n    var name: String = name\n        private set\n}
\n\n

Ou, se estiver usando data class, terá que dar um jeito:

\n\n
data class User(private val _name: String) {\n    var name: String = _name\n        private set\n}
\n\n

Sim, o data class não permite alterar a visibilidade do setter diretamente para propriedades do construtor primário. Você precisará usar um backing field.

\n\n

Erro nº 2: Confusão com backing field

\n\n

Backing field é um campo oculto que o Kotlin gera automaticamente para uma propriedade se você usar field no getter ou setter. Mas se você substituir o getter ou setter sem referenciar field, o backing field não será criado.

\n\n

Exemplo do problema:

\n\n
var counter: Int = 0\n    private set\n    get() = field * 2 // ❌ Erro: field não definido
\n\n

Não, isso não é um erro de compilação. Mas se você escrever:

\n\n
var counter: Int = 0\n    private set\n    get() = 42 // tudo ok, mas field não é usado
\n\n

Neste caso, o backing field não será criado. E se você tentar acessar field no setter, receberá um erro. A boa notícia: se você usar private set, o backing field quase sempre é criado automaticamente, porque o setter padrão usa field. Mas se você substituir o setter sem field — prepare-se para surpresas.

\n\n

Dica: sempre use field explicitamente no getter e setter se quiser trabalhar com o backing field. E lembre-se: se a propriedade não tiver um backing fie

Blogs

Book Recommendations