110 votes

Comment définir une classe de constantes en Java ?

Supposons que vous deviez définir une classe dont la seule fonction est de contenir des constantes.

public static final String SOME_CONST = "SOME_VALUE";

Quelle est la meilleure façon de procéder ?

  1. Interface
  2. Classe abstraite
  3. Classe finale

Lequel dois-je utiliser et pourquoi ?


Clarification de certaines réponses :

Enums - Je ne vais pas utiliser d'énumération, je n'énumère rien, je rassemble juste quelques constantes qui ne sont pas liées les unes aux autres de quelque manière que ce soit.

Interface - Je ne vais pas définir une classe qui implémente l'interface. Je veux juste utiliser l'interface pour appeler des constantes comme ceci : ISomeInterface.SOME_CONST .

122voto

user54579 Points 1404

Utilisez une classe finale et définissez un constructeur privé pour masquer le constructeur public.
Pour plus de simplicité, vous pouvez utiliser une importation statique pour réutiliser vos valeurs dans une autre classe

public final class MyValues {

  private MyValues() {
    // No need to instantiate the class, we can hide its constructor
  }

  public static final String VALUE1 = "foo";
  public static final String VALUE2 = "bar";
}

dans une autre classe :

import static MyValues.*
//...

if (VALUE1.equals(variable)) {
  //...
}

43voto

Jon Skeet Points 692016

Votre éclaircissement stipule ce qui suit : "Je ne vais pas utiliser d'enums, je n'énumère rien, je rassemble juste quelques constantes qui ne sont pas liées les unes aux autres de quelque manière que ce soit".

Si les constantes ne sont pas du tout liées les unes aux autres, pourquoi vouloir les rassembler ? Placez chaque constante dans la classe à laquelle elle est le plus étroitement liée.

35voto

kenj0418 Points 2428

Mes suggestions (par ordre décroissant de préférence) :

1) Ne le faites pas . Créez les constantes dans la classe réelle, là où elles sont le plus pertinentes. Avoir une classe/interface "sac de constantes" n'est pas vraiment conforme aux meilleures pratiques de l'OO.

Comme tout le monde, j'ignore le numéro 1 de temps en temps. Si c'est ce que vous faites, alors.. :

2) classe finale avec constructeur privé Cela empêchera au moins quiconque d'abuser de votre "sac de constantes" en l'étendant ou en l'implémentant pour obtenir un accès facile aux constantes. (Je sais que vous avez dit que vous ne feriez pas cela - mais cela ne veut pas dire que quelqu'un qui viendra après vous ne le fera pas).

3) interface Cela fonctionnera, mais ce n'est pas ce que je préfère, compte tenu des abus possibles mentionnés au point 2.

En général, ce n'est pas parce qu'il s'agit de constantes qu'il ne faut pas leur appliquer les principes normaux de l'oo. Si une constante n'intéresse qu'une seule classe, elle doit être privée et appartenir à cette classe. Si seuls les tests s'intéressent à une constante, elle doit se trouver dans une classe de test, et non dans le code de production. Si une constante est définie à plusieurs endroits (et pas seulement accidentellement au même endroit), il faut la remanier pour éliminer la duplication. Et ainsi de suite - traitez-les comme vous le feriez pour une méthode.

14voto

Comme le note Joshua Bloch dans Effective Java :

  • Les interfaces ne doivent être utilisées que pour définir des types,
  • Les classes abstraites n'empêchent pas l'instanciabilité (elles peuvent être sous-classées, et suggèrent même qu'elles sont conçues pour être sous-classées).

Vous pouvez utiliser une Enum si toutes vos constantes sont liées (comme les noms de planètes), placer les valeurs constantes dans les classes auxquelles elles sont liées (si vous y avez accès), ou utiliser une classe utilitaire non instanciable (en définissant un constructeur privé par défaut).

class SomeConstants
{
    // Prevents instanciation of myself and my subclasses
    private SomeConstants() {}

    public final static String TOTO = "toto";
    public final static Integer TEN = 10;
    //...
}

Ensuite, comme indiqué précédemment, vous pouvez utiliser des importations statiques pour utiliser vos constantes.

7voto

cletus Points 276888

Ma méthode préférée est de ne pas le faire du tout. L'ère des constantes a pratiquement disparu lorsque Java 5 a introduit les typesafe enums. Et même avant cela, Josh Bloch a publié une version (légèrement plus verbeuse) de cette méthode, qui fonctionnait avec Java 1.4 (et les versions antérieures).

À moins d'avoir besoin d'une interopérabilité avec un code ancien, il n'y a plus aucune raison d'utiliser des constantes nommées de type chaîne/entiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X