Public get private set dans Kotlin : pièges et solutions

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Public get, private set dans Kotlin : comment éviter les pièges (et que faire si vous êtes déjà tombé dedans)

\n\n

Bonjour, collègue ! Si tu as déjà cherché sur Google "Kotlin public get private set var", tu n'es pas seul. Cette requête est un véritable hit sur Stack Overflow, et des milliers de développeurs (moi y compris à l'époque) se sont cogné la tête contre le clavier en essayant de comprendre pourquoi leur code ne fonctionnait pas.

\n\n

Ça semble simple, non ? Je veux que la propriété soit accessible à tous (public get), mais que seul la classe puisse la modifier (private set). En Java, c'était une routine : on déclarait un champ private, on écrivait un getter et un setter, et on rendait le setter privé. Dans Kotlin, tout devrait être plus simple, mais...

\n\n

Attention, spoiler : la syntaxe existe, mais elle ne fonctionne pas toujours comme tu t'y attends. Dans cet article, nous allons passer en revue les principales erreurs que même les développeurs expérimentés commettent, et montrer comment les éviter. C'est parti !

\n\n

Anatomie d'une propriété : var, val, get et set

\n\n

Pour commencer, un petit rappel. Dans Kotlin, les propriétés ne sont pas de simples champs. Ce sont des éléments à part entière qui peuvent contenir des getters et des setters. Voici la structure de base :

\n\n
var nom_propriété: Type = valeur_par_défaut\n    get() = field\n    set(value) { field = value }
\n\n

Si tu utilises var, Kotlin génère automatiquement un getter et un setter. Mais tu peux redéfinir leur comportement. Et aussi modifier leur visibilité (modificateurs de visibilité : public, private, internal, protected).

\n\n

Et c'est là que ça devient intéressant. Pour rendre le getter public et le setter privé, il faut écrire :

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

C'est tout ? Presque. Mais il y a des nuances qui cassent ce mécanisme.

\n\n

Erreur n°1 : Oublier le constructeur

\n\n

Le problème le plus fréquent est la tentative de déclarer public get private set var dans le constructeur de la classe. Par exemple :

\n\n
// ❌ Erreur : ce n'est pas possible\nclass User(public get private set var name: String)
\n\n

Kotlin générera une erreur de compilation. Pourquoi ? Parce que les paramètres du constructeur ne sont pas des propriétés. Ce sont simplement des paramètres. Si tu veux qu'une propriété ait une visibilité de setter modifiée, tu dois la déclarer dans le corps de la classe.

\n\n

Comment faire correctement :

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

Ou, si tu utilises un data class, il faudra te débrouiller :

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

Oui, data class ne permet pas de modifier directement la visibilité du setter pour les propriétés du constructeur principal. Tu devras utiliser un champ de support.

\n\n

Erreur n°2 : Confusion avec le champ de support

\n\n

Le champ de support est un champ caché que Kotlin génère automatiquement pour une propriété si tu utilises field dans le getter ou le setter. Mais si tu redéfinis le getter ou le setter sans faire référence à field, le champ de support n'est pas créé.

\n\n

Exemple de problème :

\n\n
var counter: Int = 0\n    private set\n    get() = field * 2 // ❌ Erreur : field n'est pas défini
\n\n

Non, ce n'est pas une erreur de compilation. Mais si tu écris :

\n\n
var counter: Int = 0\n    private set\n    get() = 42 // tout va bien, mais field n'est pas utilisé
\n\n

Dans ce cas, le champ de support ne sera pas créé. Et si tu essaies d'accéder à field dans le setter, tu obtiendras une erreur. Bonne nouvelle : si tu utilises private set, le champ de support est presque toujours créé automatiquement, car le setter par défaut utilise field. Mais si tu redéfinis le setter sans field — prépare-toi à des surprises.

\n\n

Conseil : utilise toujours explicitement field dans le getter et le setter si tu veux travailler avec le champ de support. Et souviens-toi : si une propriété n'a pas de champ de support

Blogs

Book Recommendations