web-dev-qa-db-fra.com

Que sont les énumérations et pourquoi sont-elles utiles?

Aujourd'hui, je parcourais quelques questions sur ce site et j'ai trouvé une mention d'un enumtilisé dans un modèle singleton à propos des avantages supposés de la sécurité du fil par rapport à une telle solution.

Je n'ai jamais utilisé enums et je programme depuis Java depuis plus de deux ans maintenant. Et apparemment, ils ont beaucoup changé. Maintenant, ils supportent même pleinement OOP en eux-mêmes.

Maintenant, pourquoi et pour quoi devrais-je utiliser enum dans la programmation quotidienne?

461
Mat B.

Vous devez toujours utiliser des énumérations lorsqu'une variable (en particulier un paramètre de méthode) ne peut prendre qu'une parmi un petit ensemble de valeurs possibles. Des exemples sont, par exemple, les constantes de type (statut du contrat: "permanent", "temporaire", "apprenti"), ou les indicateurs ("exécuter maintenant", "différer l'exécution").

Si vous utilisez des énumérations au lieu d'entiers (ou de codes de chaîne), vous augmentez la vérification à la compilation, évitez les erreurs de transmission de constantes non valides et vous documentez les valeurs qu'il est légal d'utiliser.

BTW, une utilisation excessive d’énums peut signifier que vos méthodes en font trop (il est souvent préférable d’avoir plusieurs méthodes séparées plutôt qu’une méthode qui prend plusieurs indicateurs qui modifient ce qu’il fait), mais si vous devez utiliser des indicateurs ou des codes de type, enum sont le chemin à parcourir.

Par exemple, quel est le meilleur?

/** Counts number of foobangs.
 * @param type Type of foobangs to count. Can be 1=green foobangs,
 * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
 * @return number of foobangs of type
 */
public int countFoobangs(int type)

versus

/** Types of foobangs. */
public enum FB_TYPE {
 GREEN, WRINKLED, SWEET, 
 /** special type for all types combined */
 ALL;
}

/** Counts number of foobangs.
 * @param type Type of foobangs to count
 * @return number of foobangs of type
 */
public int countFoobangs(FB_TYPE type)

Un appel de méthode comme:

int sweetFoobangCount = countFoobangs(3);

devient alors:

int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

Dans le deuxième exemple, il est immédiatement clair quels types sont autorisés, la documentation et l'implémentation ne peuvent pas être désynchronisées, et le compilateur peut les appliquer. En outre, un appel invalide comme

int sweetFoobangCount = countFoobangs(99);

n'est plus possible.

599
sleske

Pourquoi utiliser une fonctionnalité de langage de programmation? La raison pour laquelle nous avons des langues est pour

  1. Les programmeurs peuvent efficacement et correctement exprimer des algorithmes sous une forme que les ordinateurs peuvent utiliser.
  2. Les mainteneurs doivent comprendre les algorithmes que d’autres ont écrits et correctement apportent des modifications.

Les énumérations améliorent à la fois la probabilité d’exactitude et de lisibilité sans écrire beaucoup de chiffres. Si vous êtes prêt à écrire des lettres passe-partout, vous pouvez "simuler" des énumérations:

public class Color {
    private Color() {} // Prevent others from making colors.
    public static final Color RED = new Color();
    public static final Color AMBER = new Color();
    public static final Color GREEN = new Color();
}

Maintenant vous pouvez écrire:

Color trafficLightColor = Color.RED;

Le passe-partout ci-dessus a à peu près le même effet que

public enum Color { RED, AMBER, GREEN };

Les deux fournissent le même niveau d'aide à la vérification du compilateur. Boilerplate est juste plus en tapant. Mais économiser beaucoup de texte rend le programmeur plus efficace (voir 1), donc c'est une fonctionnalité intéressante.

Cela vaut la peine pour au moins une autre raison également:

instructions Switch

Une chose que la simulation static final enum ci-dessus ne vous donne pas est Nice switch cas. Pour les types enum, le commutateur Java utilise le type de sa variable pour déduire l'étendue des cas enum. Par conséquent, pour le enum Color ci-dessus, il vous suffit de dire:

Color color = ... ;
switch (color) {
    case RED:
        ...
        break;
}

Notez que ce n'est pas Color.RED dans les cas. Si vous n'utilisez pas enum, le seul moyen d'utiliser des quantités nommées avec switch est quelque chose comme:

public Class Color {
    public static final int RED = 0;
    public static final int AMBER = 1;
    public static final int GREEN = 2;
}

Mais maintenant, une variable pour contenir une couleur doit avoir le type int. La vérification par le compilateur de Nice de l’énumération et de la simulation static final a disparu. Pas heureux.

Un compromis consiste à utiliser un membre scalaire dans la simulation:

public class Color {
    public static final int RED_TAG = 1;
    public static final int AMBER_TAG = 2;
    public static final int GREEN_TAG = 3;

    public final int tag;

    private Color(int tag) { this.tag = tag; } 
    public static final Color RED = new Color(RED_TAG);
    public static final Color AMBER = new Color(AMBER_TAG);
    public static final Color GREEN = new Color(GREEN_TAG);
}

Maintenant:

Color color = ... ;
switch (color.tag) {
    case Color.RED_TAG:
        ...
        break;
}

Mais notez bien plus encore!

tiliser une énumération comme singleton

Dans le passe-haut ci-dessus, vous pouvez voir pourquoi une énumération fournit un moyen d'implémenter un singleton. Au lieu d'écrire:

public class SingletonClass {
    public static final void INSTANCE = new SingletonClass();
    private SingletonClass() {}

    // all the methods and instance data for the class here
}

puis y accéder avec

SingletonClass.INSTANCE

on peut juste dire

public enum SingletonClass {
    INSTANCE;

    // all the methods and instance data for the class here
}

ce qui nous donne la même chose. Nous pouvons nous en sortir parce que Java enums sont implémentés en tant que classes complètes avec seulement un peu de sucre syntaxique parsemé au-dessus. C'est encore moins habituel, mais ce n'est pas évident à moins que le langage ne vous soit familier. Je n'aime pas non plus le fait que vous obteniez les différentes fonctions enum même si elles n’ont pas beaucoup de sens pour le singleton: ord et values, etc. (Il y a en fait une simulation plus délicate où Color extends Integer cela fonctionnera avec switch, mais c'est tellement compliqué qu'il montre encore plus clairement pourquoi enum est une meilleure idée.)

Sécurité du fil

La sécurité des threads est un problème potentiel uniquement lorsque des singletons sont créés paresseusement sans verrouillage.

public class SingletonClass {
    private static SingletonClass INSTANCE;
    private SingletonClass() {}
    public SingletonClass getInstance() {
        if (INSTANCE == null) INSTANCE = new SingletonClass();
        return INSTANCE;
    }

    // all the methods and instance data for the class here
}

Si plusieurs threads appellent getInstance simultanément alors que INSTANCE est toujours nul, vous pouvez créer un nombre illimité d'instances. C'est mauvais. La seule solution consiste à ajouter synchronized access pour protéger la variable INSTANCE.

Cependant, le code static final ci-dessus n'a pas ce problème. Il crée l'instance avec impatience au moment du chargement de la classe. Le chargement de classe est synchronisé.

Le singleton enum est effectivement paresseux, car il n'est pas initialisé avant la première utilisation. L'initialisation Java est également synchronisée, de sorte que plusieurs threads ne peuvent pas initialiser plus d'une instance de INSTANCE. Vous obtenez un singleton paresseusement initialisé avec très peu de code. Le seul point négatif est la syntaxe plutôt obscure. Vous devez connaître l'idiome ou bien comprendre le fonctionnement du chargement et de l'initialisation des classes pour savoir ce qui se passe.

128
Gene

Outre les cas d'utilisation déjà mentionnés, je trouve souvent des énumérations utiles pour mettre en œuvre le modèle de stratégie, en suivant certaines instructions de base OOP:

  1. Avoir le code où se trouvent les données (c'est-à-dire à l'intérieur de l'énumération elle-même - ou souvent dans les constantes d'énumération, qui peuvent remplacer les méthodes).
  2. Implémentation d'une interface (ou plus) afin de ne pas lier le code client à l'énum (qui ne devrait fournir qu'un ensemble d'implémentations par défaut).

L'exemple le plus simple serait un ensemble d'implémentations Comparator:

enum StringComparator implements Comparator<String> {
    NATURAL {
        @Override
        public int compare(String s1, String s2) {
            return s1.compareTo(s2);
        }
    },
    REVERSE {
        @Override
        public int compare(String s1, String s2) {
            return NATURAL.compare(s2, s1);
        }
    },
    LENGTH {
        @Override
        public int compare(String s1, String s2) {
            return new Integer(s1.length()).compareTo(s2.length());
        }
    };
}

Ce "modèle" peut être utilisé dans des scénarios beaucoup plus complexes, en faisant un usage intensif de tous les avantages fournis avec l'énumération: itérer sur les instances, en s'appuyant sur leur ordre implicite, récupérer une instance par son nom, des méthodes statiques fournissant la bonne instance pour des contextes spécifiques, etc. Et tout cela est toujours caché derrière l'interface pour que votre code fonctionne avec des implémentations personnalisées sans modification si vous voulez quelque chose qui n'est pas disponible parmi les "options par défaut".

Cela a été appliqué avec succès pour modéliser le concept de granularité temporelle (quotidien, hebdomadaire, etc.) où toute la logique était encapsulée dans un enum (choix de la granularité appropriée pour une plage de temps donnée, comportement spécifique lié à chaque granularité de manière constante). méthodes etc.). Et toujours, la Granularity vue par la couche service était simplement une interface.

41
Costi Ciudatu

Quelque chose dans les réponses n’ayant pas fait l’objet d’énumérations particulièrement puissantes est la possibilité d’avoir méthodes de modèle . Les méthodes peuvent faire partie de l'énumération de base et être remplacées par chaque type. Et, avec le comportement attaché à l'énum, ​​cela élimine souvent le besoin de constructions if-else ou d'instructions switch comme ceci publication d'un blog - où enum.method() fait ce qui serait exécuté à l'origine à l'intérieur du conditionnel. Le même exemple montre également l’utilisation d’importations statiques avec des enums produisant un code DSL beaucoup plus propre.

Parmi les autres qualités intéressantes, citons le fait que les enums fournissent une implémentation pour equals(), toString() et hashCode() et implémentent Serializable et Comparable.

Pour un récapitulatif complet de tout ce que les énumérations ont à offrir, je recommande vivement la version de Bruce Eckel Pensée dans Java 4ème édition qui consacre un chapitre entier au sujet. Les exemples impliquant un jeu Rock, Paper, Scissors (c.-à-d. RoShamBo) sont particulièrement éclairants.

32
orangepips

De Java documents -

Vous devez utiliser les types enum chaque fois que vous avez besoin pour représenter un ensemble fixe de constantes. Cela inclut les types d'énumérations naturelles telles que les planètes de notre système solaire et les ensembles de données dans lesquels vous connaissez toutes les valeurs possibles au moment de la compilation, par exemple les choix d'un menu, les indicateurs de ligne de commande, etc.

Un exemple courant consiste à remplacer une classe par un ensemble de constantes int statiques privées privées (dans un nombre raisonnable de constantes) par un type enum. En gros, si vous pensez connaître toutes les valeurs possibles de "quelque chose" au moment de la compilation, vous pouvez le représenter sous la forme d'un type enum. Les énumérations fournissent la lisibilité et la flexibilité sur une classe avec des constantes.

Peu d'autres avantages que je peux penser aux types enum. C'est toujours un exemple d'une classe d'énum particulière (d'où vient l'idée d'utiliser des énumérations comme singleton). Un autre avantage est que vous pouvez utiliser enums comme type dans une instruction switch-case. Vous pouvez aussi utiliser toString () sur l’énumération pour les imprimer sous forme de chaînes lisibles.

21
CoolBeans

Maintenant, pourquoi et pour quoi devrais-je utiliser enum dans la programmation quotidienne?

Vous pouvez utiliser un Enum pour représenter un petit ensemble fixe de constantes ou un mode de classe interne tout en améliorant la lisibilité. De plus, les énumérations peuvent imposer une certaine rigidité lorsqu'elles sont utilisées dans les paramètres de méthode. Ils offrent la possibilité intéressante de transmettre des informations à un constructeur comme dans le exemple de Planets sur le site d'Oracle et, comme vous l'avez découvert, offrent également un moyen simple de créer un motif singleton.

ex: Locale.setDefault(Locale.US) lit mieux que Locale.setDefault(1) et impose l'utilisation du jeu fixe de valeurs indiqué dans un IDE lorsque vous ajoutez le séparateur . à la place de tous les entiers.

18
James P.

Enums énumère un ensemble fixe de valeurs, de manière auto-documentée.
Ils rendent votre code plus explicite et moins sujet aux erreurs.

Pourquoi ne pas utiliser String ou int au lieu de Enum pour les constantes?

  1. Le compilateur n'autorise pas les typos , ni les valeurs hors de l'ensemble fixe, car les enums sont des types par eux-mêmes. Conséquences:
    • Vous n'aurez pas à écrire une pré-condition (ou un manuel if) pour vous assurer que votre argument est dans la plage valide.
    • L'invariant de type est gratuit.
  2. Les énumérations peuvent avoir un comportement, comme n'importe quelle autre classe.
  3. Vous aurez probablement besoin d’une quantité de mémoire similaire pour utiliser Strings, de toute façon (cela dépend de la complexité de Enum).

De plus, chacune des instances de Enum est une classe pour laquelle vous pouvez définir son comportement individuel.

De plus, ils assurent la sécurité des threads lors de la création des instances (lorsque l’énumération est chargée), ce qui s’est avéré très utile pour simplifier le motif Singleton .

Ce blog illustre certaines de ses applications, telles qu'une machine à états pour un analyseur.

13
afsantos

Il est utile de savoir que enums sont comme les autres classes avec les champs Constant et un private constructor.

Par exemple,

public enum Weekday
{
  MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
} 

Le compilateur le compile comme suit;

class Weekday extends Enum
{
  public static final Weekday MONDAY  = new Weekday( "MONDAY",   0 );
  public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
  public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 );
  public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 );
  public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 );
  public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 );
  public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 );

  private Weekday( String s, int i )
  {
    super( s, i );
  }

  // other methods...
}
12
Ad Infinitum

enum signifie enum eration c’est-à-dire mentionner (plusieurs choses) une par une.

Un enum est un type de données contenant un ensemble fixe de constantes.

OR

Une enum est semblable à un class, avec un ensemble fixe d'instances connues au moment de la compilation.

Par exemple:

public class EnumExample {
    interface SeasonInt {
        String seasonDuration();
    }

    private enum Season implements SeasonInt {
        // except the enum constants remaining code looks same as class
        // enum constants are implicitly public static final we have used all caps to specify them like Constants in Java
        WINTER(88, "DEC - FEB"), SPRING(92, "MAR - JUN"), SUMMER(91, "JUN - AUG"), FALL(90, "SEP - NOV");

        private int days;
        private String months;

        Season(int days, String months) { // note: constructor is by default private 
            this.days = days;
            this.months = months;
        }

        @Override
        public String seasonDuration() {
            return this+" -> "+this.days + "days,   " + this.months+" months";
        }

    }
    public static void main(String[] args) {
        System.out.println(Season.SPRING.seasonDuration());
        for (Season season : Season.values()){
            System.out.println(season.seasonDuration());
        }

    }
}

Avantages de enum:

  • enum améliore la sécurité des types lors de la vérification à la compilation pour éviter les erreurs lors de l'exécution.
  • enum peut être facilement utilisé en switch
  • l'énumération peut être parcourue
  • enum peut avoir des champs, des constructeurs et des méthodes
  • enum peut implémenter de nombreuses interfaces mais ne peut étendre aucune classe car il étend en interne la classe Enum

pour plus

11
Premraj

Qu'est-ce qu'un énum

  • enum est un mot clé défini pour Enumeration, un nouveau type de données. Les énumérations Typesafe doivent être utilisées généreusement. En particulier, elles constituent une alternative robuste aux constantes simples String ou int utilisées dans des API beaucoup plus anciennes pour représenter des ensembles d'éléments associés.

Pourquoi utiliser enum

  • les énumérations sont implicitement des sous-classes finales de Java.lang.Enum
  • si une énumération est membre d'une classe, elle est implicitement statique
  • new ne peut jamais être utilisé avec un enum, même dans le type d'énum lui-même
  • name et valueOf utilisent simplement le texte des constantes enum, tandis que toString peut être remplacé pour fournir n'importe quel contenu, si désiré
  • pour les constantes d'énumération, égal à == et équivalent à la même chose, et pouvant être utilisé indifféremment
  • les constantes enum sont implicitement publiques statiques finales

Remarque

  • les enums ne peuvent étendre aucune classe.
  • Une enum ne peut pas être une super-classe.
  • l'ordre d'apparition des constantes enum s'appelle leur "ordre naturel" et définit également l'ordre utilisé par d'autres éléments: compareTo, ordre d'itération des valeurs, EnumSet, EnumSet.range.
  • Une énumération peut avoir des constructeurs, des blocs d'instance et statiques, des variables et des méthodes, mais ne peut pas avoir de méthodes abstraites.
8
tinker_fairy

En dehors de tout ce que d'autres ont dit. Dans un projet plus ancien pour lequel je travaillais, beaucoup de communications entre entités (applications indépendantes) utilisaient des entiers, ce qui représentait un petit ensemble. Il était utile de déclarer l'ensemble comme enum avec des méthodes statiques pour obtenir l'objet enum de value et vice-versa. Le code semblait plus propre, la facilité d'utilisation des boîtiers et une écriture plus facile dans les journaux.

enum ProtocolType {
    TCP_IP (1, "Transmission Control Protocol"), 
    IP (2, "Internet Protocol"), 
    UDP (3, "User Datagram Protocol");

    public int code;
    public String name;

    private ProtocolType(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public static ProtocolType fromInt(int code) {
    switch(code) {
    case 1:
        return TCP_IP;
    case 2:
        return IP;
    case 3:
        return UDP;
    }

    // we had some exception handling for this
    // as the contract for these was between 2 independent applications
    // liable to change between versions (mostly adding new stuff)
    // but keeping it simple here.
    return null;
    }
}

Créer un objet enum à partir des valeurs reçues (par exemple 1,2) à l'aide de ProtocolType.fromInt(2) Écrire dans les journaux à l'aide de myEnumObj.name

J'espère que cela t'aides.

8
sErVerdevIL

Enum hérite de toutes les méthodes de Object class et de la classe abstraite Enum. Vous pouvez donc utiliser ses méthodes pour la réflexion, le multithreading, la sérilisation, la comparaison, etc. Si vous déclarez simplement une constante statique au lieu d’Enum, vous ne pouvez pas. En outre, la valeur de Enum peut également être transmise à la couche DAO.

Voici un exemple de programme à démontrer.

public enum State {

    Start("1"),
    Wait("1"),
    Notify("2"),
    NotifyAll("3"),
    Run("4"),
    SystemInatilize("5"),
    VendorInatilize("6"),
    test,
    FrameworkInatilize("7");

    public static State getState(String value) {
        return State.Wait;
    }

    private String value;
    State test;

    private State(String value) {
        this.value = value;
    }

    private State() {
    }

    public String getValue() {
        return value;
    }

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public boolean isNotify() {
        return this.equals(Notify);
    }
}

public class EnumTest {

    State test;

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public State getCurrentState() {
        return test;
    }

    public static void main(String[] args) {
        System.out.println(State.test);
        System.out.println(State.FrameworkInatilize);
        EnumTest test=new EnumTest();
        test.setCurrentState(State.Notify);
        test. stateSwitch();
    }

    public void stateSwitch() {
        switch (getCurrentState()) {
        case Notify:
            System.out.println("Notify");
            System.out.println(test.isNotify());
            break;
        default:
            break;
        }
    }
}
6
abishkar bhattarai

ENum signifie "type énuméré". C'est un type de données ayant un ensemble fixe de constantes que vous définissez vous-même.

4
Steve

À mon avis, toutes les réponses que vous avez données jusqu'à présent sont valables, mais d'après mon expérience, je les exprimerais en quelques mots:

tilisez enums si vous voulez que le compilateur vérifie la validité de la valeur d'un identifiant.

Sinon, vous pouvez utiliser des chaînes comme vous l'avez toujours fait (vous avez probablement défini des "conventions" pour votre application) et vous serez très flexible ... mais vous n'obtiendrez pas une sécurité à 100% contre les fautes de frappe sur vos chaînes et vous ne les réaliserez que en exécution.

3
Rafa

Enum? Pourquoi devrait-il être utilisé? Je pense que c'est plus compris quand vous allez l'utiliser. J'ai la même expérience.

Supposons que vous ayez une opération de création, suppression, édition et lecture de base de données.

Maintenant, si vous créez une énumération en tant qu’opération:

public enum operation {
    create("1")
    delete("2")
    edit("3")
    read("4")

    // You may have is methods here
    public boolean isCreate() {
        return this.equals(create);
    }
    // More methods like the above can be written

}

Maintenant, vous pouvez déclarer quelque chose comme:

private operation currentOperation;

// And assign the value for it 
currentOperation = operation.create

Vous pouvez donc l'utiliser de plusieurs manières. Il est toujours bon d'avoir enum pour des choses spécifiques, car l'opération de la base de données dans l'exemple ci-dessus peut être contrôlée en vérifiant currentOperation. On peut peut-être dire que cela peut être accompli avec des variables et des valeurs entières. Mais je crois qu'Enum est un moyen sûr et programmé.

Une autre chose: je pense que chaque programmeur aime boolean, n'est-ce pas? Parce qu'il ne peut stocker que deux valeurs, deux valeurs spécifiques. Enum peut donc être considéré comme ayant le même type d'installations où un utilisateur définira le nombre et le type de valeur qu'il stockera, mais d'une manière légèrement différente. :)

2
Abhishek Bhandari

Utilisez des énumérations pour TYPE SAFETY, il s’agit d’une fonctionnalité de langue qui vous permettra généralement d’obtenir:

  • Support du compilateur (voir immédiatement les problèmes de type)
  • Prise en charge des outils dans les IDE (complétion automatique dans les cas de commutation ...)

Les énumérations peuvent avoir des méthodes, des constructeurs, vous pouvez même utiliser des énumérations dans des énumérations et combiner des énumérations avec des interfaces.

Pensez aux énumérations en tant que types pour remplacer un ensemble bien défini de constantes int (qui Java 'hérité' de C/C++).

Le livre Effective Java 2nd Edition contient un chapitre entier à leur sujet et va dans plus de détails. Voir aussi ce message de débordement de pile .

2
Christophe Roussy

Jusqu'à présent, je n'ai jamais eu besoin d'utiliser d'énums. Je lis à leur sujet depuis qu'ils ont été introduits dans la version 1.5 ou tigre, comme cela a été appelé dans la journée. Ils n'ont jamais vraiment résolu un "problème" pour moi. Pour ceux qui l'utilisent (et j'en vois beaucoup), je suis sûr que cela sert vraiment le but certains. Juste mon 2 quid.

1
happybuddha

Il y a beaucoup de réponses ici, je veux juste en indiquer deux spécifiques:

1) Utilisation en tant que constantes dans l'instruction Switch-case. Changer de casse ne vous permettra pas d'utiliser des objets String pour cas. Les enums sont utiles. Plus: http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

2) Implémentation de Singleton Design Pattern - Enum à nouveau, vient au secours. Utilisation, ici: Quelle est la meilleure approche pour utiliser un Enum en tant que singleton en Java?

1
Vishal Verma

Java vous permet de limiter la variable à l’une des quelques valeurs prédéfinies, c’est-à-dire une valeur d’une liste énumérée. Utiliser enums peut aider à réduire les bogues dans votre code. Voici un exemple de enums en dehors d'une classe:

enums coffeesize{BIG , HUGE , OVERWHELMING }; 
//This semicolon is optional.

Ceci restreint coffeesize à _: BIG, HUGE ou OVERWHELMING en tant que variable.

1
Rahul Prajapat

Quant à moi, pour rendre le code lisible à l'avenir, le cas le plus utile de énumération est représenté dans le prochain extrait:

public enum Items {
    MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT
}

@Override
public boolean onCreateOptionsMenu(Menu menuPrm) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menuPrm);
    View itemChooserLcl;
    for (int i = 0; i < menuPrm.size(); i++) {
        MenuItem itemLcl  = menuPrm.getItem(i);
            itemChooserLcl = itemLcl.getActionView();
            if (itemChooserLcl != null) {
                 //here Im marking each View' tag by enume values:
                itemChooserLcl.setTag(Items.values()[i]);
                itemChooserLcl.setOnClickListener(drawerMenuListener);
            }
        }
    return true;
}
private View.OnClickListener drawerMenuListener=new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Items tagLcl= (Items) v.getTag();
        switch (tagLcl){
            case MESSAGES: ;
            break;
            case CHATS : ;
            break;
            case CITY_ONLINE : ;
            break;
            case FRIENDS : ;
            break;
            case  PROFILE: ;
            break;
            case  SETTINGS: ;
            break;
            case  PEOPLE_SEARCH: ;
            break;
            case  CREATE_CHAT: ;
            break;
        }
    }
};
1
CodeToLife

Ce qui m'a donné le moment Ah-Ha, c'est cette réalisation: qu'Enum a un constructeur privé uniquement accessible via l'énumération publique:

enum RGB {
    RED("Red"), GREEN("Green"), BLUE("Blue");

    public static final String PREFIX = "color ";

    public String getRGBString() {
        return PREFIX + color;
    }

    String color;

    RGB(String color) {
        this.color = color;
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        String c = RGB.RED.getRGBString();
        System.out.print("Hello " + c);
    }
}
1
djangofan

D'après mon expérience, j'ai constaté que l'utilisation d'Enum rend parfois les systèmes très difficiles à modifier. Si vous utilisez un Enum pour un ensemble de valeurs spécifiques à un domaine qui changent fréquemment et qu'il comporte de nombreuses autres classes et composants qui en dépendent, vous voudrez peut-être prendre en compte et non en utilisant un Enum.

Par exemple, un système commercial qui utilise un Enum pour les marchés/bourses. Il existe de nombreux marchés et il est presque certain que de nombreux sous-systèmes devront accéder à cette liste de marchés. Chaque fois que vous souhaitez ajouter un nouveau marché à votre système ou supprimer un marché, il est possible que tout ce qui se trouve sous le soleil doive être reconstruit et libéré.

Un meilleur exemple serait quelque chose comme un type de catégorie de produit. Supposons que votre logiciel gère l'inventaire d'un grand magasin. Il existe de nombreuses catégories de produits et de nombreuses raisons pour lesquelles cette liste de catégories pourrait changer. Les gestionnaires peuvent vouloir stocker une nouvelle ligne de produits, se débarrasser d'autres lignes de produits et éventuellement réorganiser les catégories de temps à autre. Si vous devez recréer et redéployer tous vos systèmes simplement parce que les utilisateurs veulent ajouter une catégorie de produit, vous avez choisi quelque chose qui devrait être simple et rapide (ajouter une catégorie) et l'a rendu très difficile et lent.

En bout de ligne, les énumérations sont bonnes si les données que vous représentez sont très statiques dans le temps et comportent un nombre limité de dépendances. Mais si les données changent beaucoup et ont beaucoup de dépendances, alors vous avez besoin de quelque chose de dynamique qui n'est pas vérifié au moment de la compilation (comme une table de base de données).

0
BradB

J'utiliserais les énumérations comme un instrument de mappage utile, évitant plusieurs if-else à condition que certaines méthodes soient implémentées.

public enum Mapping {

    ONE("1"),
    TWO("2");

    private String label;

    private Mapping(String label){
        this.label = label;
    }

    public static Mapping by(String label) {

        for(Mapping m: values() {
            if(m.label.equals(label)) return m;
        }

        return null;
    }

}

La méthode by(String label) vous permet donc d’obtenir la valeur Enumerated par non énuméré. De plus, on peut inventer une cartographie entre 2 enums. Peut aussi essayer "1 à plusieurs" ou "plusieurs à plusieurs" en plus de la relation par défaut "un à un"

Finalement, enum est une classe Java. Ainsi, vous pouvez avoir la méthode main à l'intérieur, ce qui peut être utile lorsque vous devez effectuer des opérations de mappage sur args immédiatement.

0
TEH EMPRAH

Au lieu de faire un tas de déclarations const int

Vous pouvez les regrouper en 1 énum

Donc tout est organisé par le groupe commun auquel ils appartiennent

0
Vincent Tang