1. Qu’est-ce que les getters et les setters
Si l’on imagine un objet comme un coffre-fort, ses champs privés en sont le contenu, et les getters et setters — les clés de compartiments séparés. Les getters permettent de savoir ce qu’il y a à l’intérieur, et les setters — d’y déposer proprement quelque chose de nouveau (à condition de ne pas y mettre, par exemple, un hérisson à la place des documents).
Getter
Un getter est une méthode publique (public) qui renvoie la valeur d’un champ privé (private). Son nom commence généralement par get + le nom du champ avec une majuscule.
public class Person {
private String name; // Champ privé
// Getter pour le champ name
public String getName() {
return name;
}
}
Setter
Un setter est une méthode publique (public) qui permet de modifier la valeur d’un champ privé. Son nom commence par set + le nom du champ avec une majuscule.
public class Person {
private String name;
// Setter pour le champ name
public void setName(String name) {
this.name = name;
}
}
Pour les champs boolean
Pour les champs de type boolean, il est d’usage d’utiliser le préfixe is dans les getters :
private boolean active;
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
2. Syntaxe et conventions de nommage
Java est un langage strict, mais pas tatillon. Il existe des conventions bien établies qui rendent votre code compréhensible pour les autres développeurs (et pour vous-même dans un mois).
- Getter : public Type getNomDuChamp()
- Setter : public void setNomDuChamp(Type value)
- Getter pour boolean : public boolean isNomDuChamp()
Le nom du champ dans la méthode s’écrit avec une majuscule : si le champ est age, les méthodes seront getAge() et setAge().
Cette convention s’inscrit dans le style JavaBeans, grâce auquel les IDE, les bibliothèques et les frameworks peuvent trouver automatiquement vos getters et setters. Par exemple, si vous utilisez Spring ou JavaFX, ces méthodes seront appelées « magiquement » lorsque nécessaire.
3. Exemples de code
Prenons un projet d’apprentissage — une petite application de « contacts » (analogue d’un carnet d’adresses) — et ajoutons-y des getters et setters corrects.
Exemple : classe Contact avec champs privés et getters/setters
public class Contact {
private String name;
private String phone;
private int age;
private boolean favorite;
// Getters
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
public int getAge() {
return age;
}
public boolean isFavorite() {
return favorite;
}
// Setters
public void setName(String name) {
this.name = name;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setAge(int age) {
// Exemple de validation : l’âge ne doit pas être négatif
if (age < 0) {
System.out.println("L’âge ne peut pas être négatif !");
return;
}
this.age = age;
}
public void setFavorite(boolean favorite) {
this.favorite = favorite;
}
}
Utilisation dans l’application
Contact friend = new Contact();
friend.setName("John Doe");
friend.setPhone("+1-999-123-45-67");
friend.setAge(25);
friend.setFavorite(true);
System.out.println("Nom : " + friend.getName());
System.out.println("Téléphone : " + friend.getPhone());
System.out.println("Âge : " + friend.getAge());
System.out.println("Favori : " + (friend.isFavorite() ? "Oui" : "Non"));
Exemple de validation dans un setter
Notez que dans le setter setAge, nous avons ajouté un contrôle simple : si l’âge est négatif, nous ne modifions pas le champ et affichons un avertissement. C’est un moyen simple de protéger l’objet contre des données incorrectes.
4. Bonnes pratiques : comment bien faire
Tous les champs n’ont pas besoin de setters publics
Parfois un champ doit être en lecture seule — par exemple, un identifiant unique défini à la création de l’objet et qui ne change plus. Dans ce cas, on ne fournit pas de setter :
public class Contact {
private final int id; // final — ne peut pas être modifié après l’initialisation
public Contact(int id) {
this.id = id;
}
public int getId() {
return id;
}
// Pas de setId !
}
Utilisez les getters/setters pour contrôler l’accès et valider
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
System.out.println("Le nom ne peut pas être vide !");
return;
}
this.name = name;
}
Ne divulguez pas directement les objets internes mutables
Si vous avez un champ — par exemple, un tableau de numéros de téléphone :
private String[] phones;
Il ne faut pas le retourner directement via un getter :
public String[] getPhones() {
return phones; // Mauvais !
}
Un tel code permet au code externe de modifier le tableau comme il veut — en violant l’encapsulation !
Mieux : retourner une copie du tableau :
public String[] getPhones() {
return Arrays.copyOf(phones, phones.length); // On renvoie une copie
}
Ou simplement cloner :
public String[] getPhones() {
return phones.clone();
}
Rendez les getters et setters clairs et simples
- N’écrivez pas de logique métier complexe dans les getters/setters — leur rôle est simple : contrôle d’accès et, si nécessaire, validation.
- Si un champ ne doit pas changer — ne fournissez pas de setter.
- Si un champ ne doit pas être accessible depuis l’extérieur — ne fournissez pas de getter.
5. Génération automatique de getters/setters dans l’IDE
Écrire des accesseurs à la main n’est pas une partie de plaisir, surtout si la classe a une dizaine de champs. Heureusement, les IDE modernes (par exemple, IntelliJ IDEA, Eclipse, VS Code avec des extensions) savent les générer automatiquement.
Dans IntelliJ IDEA
- Ouvrez la classe et placez le curseur dans le corps de la classe.
- Appuyez sur Alt + Insert (ou Code -> Generate...).
- Choisissez Getter and Setter.
- Cochez les champs voulus et cliquez sur OK.
Et voilà ! Vos getters et setters apparaissent comme par magie.
Dans Eclipse
- Ouvrez la classe.
- Clic droit — Source — Generate Getters and Setters...
- Sélectionnez les champs et cliquez sur OK.
Dans VS Code (avec Java Extension Pack)
- Ouvrez le fichier de classe.
- Dans la palette de commandes (Ctrl+Shift+P), tapez Generate getters and setters.
- Suivez les indications.
6. Faites évoluer votre application : l’encapsulation en action
Dans les leçons précédentes, vous avez construit une petite application de gestion de contacts. Nous pouvons maintenant l’améliorer en rendant les champs privés et en n’accordant l’accès qu’au moyen de getters/setters.
Avant (mauvais exemple) :
public class Contact {
public String name;
public String phone;
public int age;
}
Problème : n’importe quel code peut faire ceci :
Contact c = new Contact();
c.age = -1000; // Nous avons maintenant un vampire dans le carnet d’adresses !
Après (bon exemple) :
public class Contact {
private String name;
private String phone;
private int age;
public void setAge(int age) {
if (age < 0) {
System.out.println("L’âge ne peut pas être négatif !");
return;
}
this.age = age;
}
public int getAge() {
return age;
}
// Les autres getters/setters...
}
Il est désormais impossible de casser l’objet de l’extérieur, par accident (ou volontairement).
7. Getters/setters pour des propriétés calculées et immuables
Parfois, la valeur n’est pas stockée dans un champ mais calculée à la volée :
public class Rectangle {
private int width;
private int height;
public int getArea() {
return width * height;
}
}
Pas besoin de setter pour la surface — on ne peut pas la définir directement, seulement modifier la largeur ou la hauteur.
8. Getters et setters : erreurs courantes
Erreur n° 1 : un getter/setter viole l’encapsulation.
Si un getter renvoie une référence vers un objet interne mutable (par exemple, un tableau), le code externe peut le modifier en contournant toutes les vérifications. Cela sape l’idée d’encapsulation.
Erreur n° 2 : le setter ne valide pas les données.
Si un setter se contente d’assigner la valeur sans la vérifier, on peut obtenir un état invalide de l’objet (par exemple, un âge négatif ou un nom vide).
Erreur n° 3 : générer automatiquement des setters pour tous les champs.
Une IDE peut générer des setters pour tous les champs, mais ce n’est pas toujours approprié ! Par exemple, pour l’identifiant (id), un setter n’est pas nécessaire.
Erreur n° 4 : logique complexe dans les getters/setters.
Les getters et setters doivent rester simples. S’ils commencent à contenir une logique métier complexe, il vaut mieux l’extraire dans des méthodes dédiées.
Erreur n° 5 : non-respect des conventions de nommage.
Si vous nommez un getter fetchName() au lieu de getName(), certains frameworks et bibliothèques ne pourront pas l’identifier.
GO TO FULL VERSION