Modificateur d'accès Java 'public'

1. Vue d'ensemble

Dans cet article rapide, nous aborderons en détail le modificateur public , et nous discuterons du moment et de la manière de l'utiliser avec les classes et les membres.

De plus, nous illustrerons les inconvénients de l'utilisation de champs de données publics.

Pour un aperçu général des modificateurs d'accès, consultez notre article sur les modificateurs d'accès en Java.

2. Quand utiliser le modificateur d'accès public

Les classes et interfaces publiques, ainsi que les membres publics, définissent une API. C'est cette partie de notre code que les autres peuvent voir et utiliser pour contrôler le comportement de nos objets.

Cependant, une utilisation excessive du modificateur public viole le principe d'encapsulation de la programmation orientée objet (POO) et présente quelques inconvénients:

  • Cela augmente la taille d'une API, ce qui rend son utilisation plus difficile pour les clients
  • Il devient de plus en plus difficile de changer notre code parce que les clients en dépendent - tout changement futur pourrait casser leur code

3. Interfaces et classes publiques

3.1. Interfaces publiques

Une interface publique définit une spécification qui peut avoir une ou plusieurs implémentations. Ces implémentations peuvent être fournies par nous ou écrites par d'autres.

Par exemple, l'API Java expose l' interface de connexion pour définir les opérations de connexion à la base de données, laissant l'implémentation réelle à chaque fournisseur. Au moment de l'exécution, nous obtenons la connexion souhaitée en fonction de la configuration du projet:

Connection connection = DriverManager.getConnection(url);

La méthode getConnection renvoie une instance d'une implémentation spécifique à une technologie.

3.2. Cours publics

Nous définissons des classes publiques afin que les clients puissent utiliser leurs membres par instanciation et référencement statique:

assertEquals(0, new BigDecimal(0).intValue()); // instance member assertEquals(2147483647, Integer.MAX_VALUE); // static member 

De plus, nous pouvons concevoir des classes publiques pour l'héritage en utilisant le modificateur abstrait facultatif . Lorsque nous utilisons le modificateur abstrait , la classe est comme un squelette qui a des champs et des méthodes pré-implémentées que toute implémentation concrète peut utiliser , en plus d'avoir des méthodes abstraites que chaque sous-classe doit implémenter.

Par exemple, le framework de collections Java fournit la classe AbstractList comme base pour créer des listes personnalisées:

public class ListOfThree extends AbstractList { @Override public E get(int index) { //custom implementation } @Override public int size() { //custom implementation } }

Donc, nous n'avons qu'à implémenter les méthodes get () et size () . D'autres méthodes comme indexOf () et containsAll () sont déjà implémentées pour nous.

3.3. Classes et interfaces publiques imbriquées

À l'instar des classes et interfaces publiques de premier niveau, les classes et interfaces publiques imbriquées définissent un type de données API. Cependant, ils sont particulièrement utiles de deux manières:

  • Ils indiquent à l'utilisateur final de l'API que le type de niveau supérieur englobant et ses types inclus ont une relation logique et sont utilisés ensemble
  • Ils rendent notre base de code plus compacte en réduisant le nombre de fichiers de code source que nous aurions utilisés si nous les avions déclarés comme des classes et des interfaces de premier niveau

Un exemple est la carte . Interface d' entrée de l'API Java principale:

for (Map.Entry entry : mapObject.entrySet()) { }

Faire une carte . L'entrée d'une interface imbriquée la relie fortement à l' interface java.util.Map et nous a évité de créer un autre fichier dans le package java.util .

Veuillez lire l'article sur les classes imbriquées pour plus de détails.

4. Méthodes publiques

Les méthodes publiques permettent aux utilisateurs d'exécuter des opérations prêtes à l'emploi. Un exemple est la méthode publique toLowerCase dans l' API String :

assertEquals("alex", "ALEX".toLowerCase());

Nous pouvons en toute sécurité rendre statique une méthode publique si elle n'utilise aucun champ d'instance. La méthode parseInt de la classe Integer est un exemple de méthode statique publique:

assertEquals(1, Integer.parseInt("1"));

Les constructeurs sont généralement publics afin que nous puissions instancier et initialiser des objets, bien que parfois ils puissent être privés comme dans les singletons.

5. Champs publics

Les champs publics permettent de changer directement l'état d'un objet. La règle de base est que nous ne devrions pas utiliser de champs publics. Il y a plusieurs raisons à cela, comme nous allons le voir.

5.1. Thread-Safety

Using public visibility with non-final fields or final mutable fields is not thread-safe. We can't control changing their references or states in different threads.

Please check our article on thread-safety to learn more about writing thread-safe code.

5.2. Taking Actions on Modifications

We have no control over a non-final public field because its reference or state can be set directly.

Instead, it's better to hide the fields using a private modifier and use a public setter:

public class Student { private int age; public void setAge(int age) { if (age  150) { throw new IllegalArgumentException(); } this.age = age; } }

5.3. Changing the Data Type

Public fields, mutable or immutable, are part of the client's contract. It's harder to change the data representation of these fields in a future release because clients may need to refactor their implementations.

En donnant aux champs une portée privée et en utilisant des accesseurs, nous avons la possibilité de changer la représentation interne tout en conservant l'ancien type de données:

 public class Student { private StudentGrade grade; //new data representation public void setGrade(int grade) { this.grade = new StudentGrade(grade); } public int getGrade() { return this.grade.getGrade().intValue(); } }

La seule exception pour l'utilisation de champs publics est l'utilisation de champs immuables finaux statiques pour représenter des constantes:

public static final String SLASH = "/";

6. Conclusion

Dans ce tutoriel, nous avons vu que le modificateur public est utilisé pour définir une API.

De plus, nous avons décrit comment une utilisation excessive de ce modificateur peut restreindre la capacité à apporter des améliorations à notre implémentation.

Enfin, nous avons expliqué pourquoi l'utilisation de modificateurs publics pour les champs est une mauvaise pratique.

Et, comme toujours, les exemples de code de cet article sont disponibles à l'adresse over sur GitHub.