371 votes

Quelle est la meilleure façon d'implémenter les constantes en Java ?

J'ai vu des exemples comme celui-ci :

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

et j'ai supposé que je pouvais avoir une classe Constants pour envelopper les constantes, en les déclarant static final. Je ne connais pratiquement rien à Java et je me demande si c'est la meilleure façon de créer des constantes.

1 votes

Juste pour ajouter constantes java : public/privé

0 votes

5voto

Rob Dickerson Points 758

Je suis d'accord pour dire que l'utilisation d'une interface n'est pas la solution. Éviter ce modèle a même son propre article (n° 18) dans l'ouvrage de Bloch intitulé Java efficace .

L'argument de Bloch contre le modèle d'interface constante est que l'utilisation des constantes est un détail de mise en œuvre, mais que la mise en œuvre d'une interface pour les utiliser expose ce détail de mise en œuvre dans votre API exportée.

En public|private static final TYPE NAME = VALUE; est un bon moyen de déclarer une constante. Personnellement, je pense qu'il est préférable d'éviter de créer une classe séparée pour abriter toutes vos constantes, mais je n'ai jamais vu de raison de ne pas le faire, si ce n'est une préférence personnelle et un style.

Si vos constantes peuvent être bien modélisées sous forme d'énumération, envisagez l'option enum structure disponible dans la version 1.5 ou ultérieure.

Si vous utilisez une version antérieure à la 1.5, vous pouvez toujours réaliser des énumérations sûres en utilisant des classes Java normales. (Voir ce site pour en savoir plus à ce sujet).

5voto

itpres Points 157

Je préfère utiliser des getters plutôt que des constantes. Ces getters peuvent renvoyer des valeurs constantes, par exemple public int getMaxConnections() {return 10;} mais tout ce qui a besoin de la constante passera par un getter.

L'un des avantages est que si votre programme dépasse la constante - et que vous trouvez qu'elle doit être configurable - vous pouvez simplement changer la façon dont le getter renvoie la constante.

L'autre avantage est que pour modifier la constante, il n'est pas nécessaire de recompiler tout ce qui l'utilise. Lorsque vous faites référence à un champ final statique, la valeur de cette constante est compilée dans tout le bytecode qui y fait référence.

4voto

Lorand Bendig Points 5616

Sur la base des commentaires ci-dessus, je pense que c'est une bonne approche pour changer la classe de constante globale à l'ancienne (ayant des variables statiques publiques finales) en son équivalent de type enum d'une manière comme celle-ci :

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_HOST("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Ainsi, je peux les référer à des gens comme :

Constants.StringConstant.DB_HOST

3voto

Bradley Harris Points 624

Une bonne conception orientée objet ne devrait pas avoir besoin de beaucoup de constantes accessibles au public. La plupart des constantes doivent être encapsulées dans la classe qui en a besoin pour faire son travail.

2voto

djangofan Points 6046

Il y a un certain nombre d'opinions pour répondre à cette question. Pour commencer, les constantes en Java sont généralement déclarées comme étant publiques, statiques et finales. Les raisons en sont les suivantes :

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Je n'utiliserais jamais une interface pour un objet/accesseur CONSTANTS simplement parce que les interfaces sont généralement censées être implémentées. Cela ne serait-il pas amusant ?

String myConstant = IMyInterface.CONSTANTX;

Au lieu de cela, je choisirais entre plusieurs méthodes différentes, basées sur quelques petits compromis, et cela dépend donc de ce dont vous avez besoin :

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe

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