IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Constantes de classes ou enumération ?


Sujet :

Langage Java

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Points : 136
    Points
    136
    Par défaut Constantes de classes ou enumération ?
    Bonjour,

    Avant JDK 1.5, on utilisait une classe avec différents attributs en static final afin de représenté une valeur par une constante compréhensible par l'être humain.
    Chaque valeur est donc compilé dans une classe qui ne contient que ça mais qui pourrait contenir un ensemble de méthode permettant de gérer cette classe mais sans associer un objet et donc des méthodes à chaque valeur de constantes.

    Avec JDK 1.5, on a plus tendance à utiliser les type d'énumération comme le propose la documentation.
    Les énumérations créent un objet avec un constructeur en se basant sur la structure de "class" qu'on lui aura donné.
    C'est à dire que chaque énumération est un objet de l'énumération même, toutes les méthodes et attributs d'une énumération sont propres (à relativiser tout de même) à chaque membre de l'énumération.
    Ainsi dans une énumération, on ne définit pas l'objet énuméré lui même mais plutot chaque énumération de cet objet.

    Ma question s'adresse essentiellement à ceux qui connaissent au moins cela !

    Mon cas: (à titre principalement indicatif)
    Je souhaite créé un lot de ressources (bois, or, fer, etc...) pour un jeu.
    Pour les utiliser, j'ai besoin de pouvoir y associer un entier (pour des Arrays) et d'y avoir accès via le nom de cette ressource dans une classe/énumération, e.g Resources.WOOD .
    Je dois pouvoir lire ces Ressources en boucle afin d'effectuer un traitement pour chacune d'elle dans différents tableaux et différentes classes.
    Je dois pouvoir aussi, si possible, créé des sous énumérations de l'énumération de ces ressources afin de rassembler les ressources en des sortes de groupes que je devrais aussi pouvoir lire en boucle.
    Le jeu est complet et donc très lourd, je souhaite l'optimiser un maximum afin d'y permettre une forte utilisation.

    Mes questions:
    Est-il préférable d'utiliser les constantes de classe (static final ...) ou d'utiliser une enum ?
    Une énumération ne serait pas trop lourde pour une forte utilisation ?!
    Avez vous d'autres idées ou propositions à ajouter ?!

    Sources:
    informit.com (en)
    Doc Enum Types (en)
    Doc Enums (en)

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Est-il préférable d'utiliser les constantes de classe (static final ...) ou d'utiliser une enum ?

    Les enums ont été créées pour résoudre tout un tas de problèmes liés aux constantes, la plus important étant la confusion des types, donc il n'y a pas de raison de se priver de l'enum

    Une énumération ne serait pas trop lourde pour une forte utilisation ?!

    rien que dans le jvm de base, je suis sur qu'il y a déjà un très gros paquet d'enums



    Avez vous d'autres idées ou propositions à ajouter ?!

    attention pour les sous-type. Les enums ne peuvent pas être hérités. Maintenant, les int non plus, donc je sais pas comment tu imaginais faire ça avec juste des int
    aussi, les enum ont déjà un index intrinsèque que tu peux utiliser (méthode ordinal())

    Donc au final, coté mémoire, un enum ce sera:
    un référence à sa classe, un index, et un nom, bref pas de quoi tuer ta mémoir, tu peux déjà en mettre quelques milliers avant de commencer à perdre de la place

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juillet 2010
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 19
    Points : 29
    Points
    29
    Par défaut
    Si tu appeles sous-énumération un sous-ensemble de l'énumération, tu peux jeter un coup d'oeil à java.util.EnumMap et java.util.EnumSet qui sont des collections optimisées pour les enum.

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par IGstaff Voir le message
    Je souhaite créé un lot de ressources (bois, or, fer, etc...) pour un jeu.
    Les enums sont très adaptés pour représenter un ensemble d'élément commun :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    enum Resources {
        WOOD, GOLD, IRON; 
    }
    Citation Envoyé par IGstaff Voir le message
    Pour les utiliser, j'ai besoin de pouvoir y associer un entier (pour des Arrays)
    Chaque élément d'une enum est associé à son index, selon son ordre de déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Resource.WOOD.ordinal()
    Mais tu peux très bien personnaliser cela via un constructeur et un getter si besoin.

    Citation Envoyé par IGstaff Voir le message
    Je dois pouvoir lire ces Ressources en boucle afin d'effectuer un traitement pour chacune d'elle dans différents tableaux et différentes classes.
    Les enums proposent une méthode values() te retournant toutes les valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (Resource res : Resource.values()) {
        // Traitement sur 'res'
    }
    Citation Envoyé par IGstaff Voir le message
    Je dois pouvoir aussi, si possible, créé des sous énumérations de l'énumération de ces ressources afin de rassembler les ressources en des sortes de groupes que je devrais aussi pouvoir lire en boucle.
    La j'ai un peu de mal à comprendre le besoin exact ? Tu veux faire une liste de ressource c'est ça ?

    Citation Envoyé par IGstaff Voir le message
    Le jeu est complet et donc très lourd, je souhaite l'optimiser un maximum afin d'y permettre une forte utilisation.
    Je ne pense pas que le choix entre enum et/ou constante soit si déterminant dans l'optimisation d'une application. Je pencherais plutôt vers les algos dans ce cas là...


    Citation Envoyé par IGstaff Voir le message
    Est-il préférable d'utiliser les constantes de classe (static final ...) ou d'utiliser une enum ?
    Tu as besoin d'utiliser une liste fixe de ressources, donc les enums me semblent tout indiqué et proposent pleins d'avantages.


    • On peut les lister facilement via la méthode values()
    • On peut typer fortement nos méthodes, en leurs donnant le type de l'enum et non pas un vulgaire int dont on ne sait rien. Ainsi tu es sûr de ne pas utiliser de valeurs incorrect (mis à part null).
    • Les enums disposent d'une méthode toString() qui peut faciliter le débuggage : Pas besoin de connaitre la valeur de la constante on a directement son nom
    • On peut faire des conversions enum->String et String->enum via les méthode name() et valueOf() :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      String text = Resource.WOOD.name();
      System.out.println(text); // WOOD
      Resource r = Resource.valueOf(text);
    • On peut y définir des attributs, et donc l'enrichir de nouvelles informations.
    • On peut y définir des méthodes, et donc y regrouper les traitements.
    • Les EDIs savent les gérer et peuvent te proposer une complétion adapté, alors que c'est difficile voir quasi-impossible avec des constantes...



    Franchement : je ne vois aucun avantage à utiliser des constantes à la place des enums dans ce cas précis...


    Citation Envoyé par IGstaff Voir le message
    Une énumération ne serait pas trop lourde pour une forte utilisation ?!
    Pourquoi ? Au lieu de manipuler un int tu manipules une référence. Généralement cela occupe le même espace mémoire.

    Encore une fois ce serait plutôt du coté des algos qu'il faudra se tourner...


    a++

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Points : 136
    Points
    136
    Par défaut
    Merci pour toutes vos réponses.

    Sachez que je connais déjà ordinal(), values(), name() et compagnie...
    Je me suis renseigné auprès de la doc et de Eclipse pour tout savoir sur les Enum elles même.

    j'ai beaucoup plus de mal avec HashSet Et HashMap dont j'ai compris l'importance mais pas le fonctionnement (mais y'a la doc et des tutos si je veux approfondir, je ne sais juste pas si cela va me servir maintenant).

    Le problème se pose car les constantes de classes ne sont que des int et sont accessible immédiatement par le programme.
    Alors qu'apparemment, l'Enum es en fait une "sorte de collection" qui enregistre un String (Je suppose que c'est en partie, un attribut ?) dans un "tableau" et quand on appelle un des membres, la jvm* cherche dans ce tableau, la chaine correspondante dans ce tableau, ce qui est plus lourd qu'un accès direct sur référence.

    Quand je parlais de sous énumération, j'ai bien cité le mot "groupe".
    C'est à dire que j'ai une énumération comprenant toutes les ressources et je veux pouvoir créer une autre énumération ne comprenant que certaines de ces ressources en utilisant, si possible, les référence de la première énumération.
    Ma prof de JAVA m'avait montré une technique mais c'était en TP et je ne m'en souviens plus.


    *Je me suis tenté à l'utilisation de ce terme que je trouve ambigu. J'espère qu'il s'agit bien de cela. J'ai une fâcheuse tendance à ne pas retenir les termes techniques propres à un langage.

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    pour les groupes de ressource, je suppose que tu pense à ça?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    enum Resources {
        WOOD, STRAW,  GOLD, IRON, FISH; 
    }
    enum ResourceCategories {
       METAL({GOLD,IRON}), VEGETAL({WOOD,STRAW}), FOOD({FISH});
     
     
       private Resources[] resources;
       ResourceCategories(Resources[] resources){
           this.resources = resources;
       }
       public Resources[] getResources(){return resources;}
    }

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juillet 2010
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 19
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par IGstaff Voir le message
    quand on appelle un des membres, la jvm cherche dans ce tableau, la chaine correspondante dans ce tableau...
    D'où tu sors ça ?

    A mon sens, pour la jvm une enum A n'est qu'une sous-classe de java.util.Enum. Lorsque tu manipules une instance de l'enum A, cela se fait par référence comme pour n'importe quel Object.

  8. #8
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par IGstaff Voir le message
    j'ai beaucoup plus de mal avec HashSet Et HashMap dont j'ai compris l'importance mais pas le fonctionnement (mais y'a la doc et des tutos si je veux approfondir, je ne sais juste pas si cela va me servir maintenant).
    Ce sont simplement des classes permettant de gérer des collections d'objets (enums ou non).

    Citation Envoyé par IGstaff Voir le message
    Le problème se pose car les constantes de classes ne sont que des int et sont accessible immédiatement par le programme.
    Alors qu'apparemment, l'Enum es en fait une "sorte de collection" qui enregistre un String (Je suppose que c'est en partie, un attribut ?) dans un "tableau" et quand on appelle un des membres, la jvm* cherche dans ce tableau, la chaine correspondante dans ce tableau, ce qui est plus lourd qu'un accès direct sur référence.
    Non : les enums sont des objets. Donc tu manipules directement une référence (ce qui occupe la même place qu'un int). En gros c'est à peu près comme si tu faisait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Resource extends java.lang.Enum {
        public static final Resource WOOD = new Resource("WOOD", 0);
        public static final Resource GOLD = new Resource("GOLD", 1);
        public static final Resource IRON = new Resource("IRON", 2);
     
     
        private Resource(String name, int ordinal) {
            super(name, ordinal);
        }
    }
    Il n'y a pas de tableau mis à part avec la méthode values() qui te retourne un tableau. Mais encore une fois il n'y a rien de "lourd" là dedans...


    Encore une fois si tu cherches des optimisations à tout bout de champs tu te trompes de cible


    a++

  9. #9
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Encore une fois si tu cherches des optimisations à tout bout de champs tu te trompes de cible
    Précisons :

    De manière générale, l'optimisation en Java et en d'autres langages à machine virtuelle, ce n'est pas utiliser telle syntaxe de langage plutôt que telle autre. C'est réduire la complexité de l'algorithme théorique.

    enums ou constantes, cela change-t-il quelque chose à l'algorithme théorique ?
    Non => Ce n'est pas une question d'optimisation.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Points : 136
    Points
    136
    Par défaut
    Je vous remercie grandement pour toutes vos réponses, vous avez éclairci mes idées !

    @thelvin , je ne m'y prendrai pas de la même manière pour traiter l'un ou l'autre.

    @tchize_ , merci de cette indication, je vais me tourner vers cela !

    D'après la source de Enum, je peux en déduire que l'explication de adiGuba est juste et me permet donc de continuer avec les énumérations.

    En espérant que ce topic aiguillera d'autres sceptiques à l'avenir !

  11. #11
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par IGstaff Voir le message
    @thelvin , je ne m'y prendrai pas de la même manière pour traiter l'un ou l'autre.
    Au point que ça change la complexité de l'algorithme ?
    Je ne dis pas que c'est impossible car l'emploi d'Enum permet certaines prouesses de construction assez contraignantes à refaire avec de simples int constants... Mais ça me paraît douteux.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Points : 136
    Points
    136
    Par défaut
    Ca ne changera pas la complexité de mes algorithmes ici normalement.

    Je dois revenir sur ce qu'a dit tchize_ :
    Citation Envoyé par tchize_ Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    enum Resources {
        WOOD, STRAW,  GOLD, IRON, FISH; 
    }
    enum ResourceCategories {
       METAL({GOLD,IRON}), VEGETAL({WOOD,STRAW}), FOOD({FISH});
     
     
       private Resources[] resources;
       ResourceCategories(Resources[] resources){
           this.resources = resources;
       }
       public Resources[] getResources(){return resources;}
    }
    Ce code ne fonctionne pas au niveau de METAL({GOLD,IRON}) . {GOLD,IRON} est bien la déclaration d'un array mais Eclipse me refuse les "}" dans la déclaration des constantes d'une énumération.
    C'est à dire qu'il me sort l'erreur:
    Syntax error, insert "Identifier" to complete EnumConstant
    Au niveau du "}" fermant le tableau et au "{" ouvrant mon énumération, l'erreur:
    Syntax error on token "{", @ expected after this token
    Le code complet (ou pas):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public enum ResourcesType {
    	//Enumeration
    	CHILLED ({ Resource.WOOD });
    }
    (Je n'ai pas mis les méthodes et attributs en fait car ils sont inutiles, ce sont les même que sur le code de tchize_ avec les bons termes)

    NB: C'est encore un test, les groupes de ressources sont faux.

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    j'ai tappé dans le vavite sans tester

    ce code sera plus correct, je pense

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    METAL(new Resources[] {GOLD,IRON} )

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 155
    Points : 199
    Points
    199
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    pour les groupes de ressource, je suppose que tu pense à ça?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    enum Resources {
        WOOD, STRAW,  GOLD, IRON, FISH; 
    }
    enum ResourceCategories {
       METAL(new Resources[] {GOLD,IRON}), VEGETAL(new Resources[] {WOOD,STRAW}), FOOD(new Resources[] {FISH});
     
     
       private Resources[] resources;
       ResourceCategories(Resources[] resources){
           this.resources = resources;
       }
       public Resources[] getResources(){return resources;}
    }
    encore mieux (et qui marche, en principe)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    enum Resources {
        WOOD, STRAW,  GOLD, IRON, FISH; 
    }
    enum ResourceCategories {
       METAL(GOLD,IRON), VEGETAL(WOOD,STRAW), FOOD(FISH);
     
     
       private Resources[] resources;
       ResourceCategories(Resources... resources){
           this.resources = resources;
       }
       public Resources[] getResources(){return resources;}
    }
    Cela rend le code plus lisible!

  15. #15
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Points : 136
    Points
    136
    Par défaut
    Merci pour ces 2 subtilités du langage très intéressantes !

Discussions similaires

  1. [PHP 5.0] Écriture de constante de classe dynamique
    Par metfan dans le forum Langage
    Réponses: 8
    Dernier message: 14/05/2009, 09h44
  2. Constante de classe
    Par Morgoth777 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 22/07/2008, 09h24
  3. [débutant] Syntaxe d'une constante de classe
    Par alone dans le forum C++
    Réponses: 5
    Dernier message: 14/02/2008, 21h05
  4. [débutant]Définir constante dans classe
    Par Clark dans le forum C++
    Réponses: 11
    Dernier message: 11/05/2006, 17h43
  5. constante de class
    Par jeff_! dans le forum Langage
    Réponses: 6
    Dernier message: 27/12/2005, 14h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo