web-dev-qa-db-fra.com

Quelle est l'utilisation de "enum" en Java?

J'ai donc examiné ce type "enum", et cela me semble être un glorifié tablea/ArrayList/List. A quoi sert-il exactement?

66
ZimZim

Enum sert comme un type de nombre fixe de constantes et peut être utilisé au moins pour deux choses

constant

public enum Month {
    JANUARY, FEBRUARY, ...
}

C'est beaucoup mieux que de créer un groupe de constantes entières.

créant un singleton

public enum Singleton {
    INSTANCE

   // init
};

Vous pouvez faire des choses assez intéressantes avec des énumérations, regardez ici

Regardez aussi le documentation officielle

70
user219882

Vous utilisez un enum au lieu d'un class si la classe doit avoir un nombre fixe d'instances .

Exemples:

  • DayOfWeek = 7 instances → enum
  • CardSuit = 4 instances → enum
  • Singleton = 1 instance → enum

  • Product = nombre variable d'instances → class
  • User = nombre variable d'instances → class
  • Date = nombre variable d'instances → class
72
aioobe

Un type énuméré est essentiellement un type de données qui vous permet de décrire chaque membre d'un type de manière plus lisible et fiable.

Voici un exemple simple pour expliquer pourquoi:

En supposant que vous écrivez une méthode qui a quelque chose à voir avec les saisons:

Le modèle int enum

D'abord, vous avez déclaré que certaines constantes int statiques représentaient chaque saison.

public static final int SPRING = 0;
public static final int SUMMER = 1;
public static final int FALL = 2;
public static final int WINTER = 2;

Ensuite, vous avez déclaré une méthode pour imprimer le nom de la saison dans la console.

public void printSeason(int seasonCode) {
    String name = "";
    if (seasonCode == SPRING) {
        name = "Spring";
    }
    else if (seasonCode == SUMMER) {
        name = "Summer";
    }
    else if (seasonCode == FALL) {
        name = "Fall";
    }
    else if (seasonCode == WINTER) {
        name = "Winter";
    }
    System.out.println("It is " + name + " now!");
}

Donc, après cela, vous pouvez imprimer un nom de saison comme celui-ci.

printSeason(SPRING);
printSeason(WINTER);

C'est une manière assez commune (mais mauvaise) de faire différentes choses pour différents types de membres dans une classe. Cependant, comme ce code implique des entiers, vous pouvez aussi appeler la méthode comme ceci sans aucun problème.

printSeason(0);
printSeason(1);

ou même comme ça

printSeason(x - y);
printSeason(10000);

Le compilateur ne se plaindra pas car ces appels de méthodes sont valides et votre méthode printSeason peut toujours fonctionner.

Mais quelque chose ne va pas ici. Qu'est-ce qu'un code de saison de 10000 supposé signifier? Et qu'est-ce qui se passerait si x - y donne un nombre négatif? Lorsque votre méthode reçoit une entrée qui n'a pas de sens et qui n'est pas supposée être là, votre programme n'en sait rien.

Vous pouvez résoudre ce problème, par exemple, en ajoutant une vérification supplémentaire.

...
else if (seasonCode == WINTER) {
    name = "Winter";
}
else {
    throw new IllegalArgumentException();
}
System.out.println(name);

Maintenant, le programme lancera un RunTimeException lorsque le code de saison est invalide. Cependant, vous devez encore décider comment vous allez gérer l'exception.

En passant, je suis sûr que vous avez remarqué que le code de FALL et WINTER est égal à 2, non?

Vous devriez avoir l'idée maintenant. Ce modèle est fragile. Cela vous fait écrire des contrôles de condition partout. Si vous créez un jeu et que vous souhaitez ajouter une saison supplémentaire dans votre monde imaginaire, ce modèle vous fera utiliser toutes les méthodes permettant de faire les choses en fonction des saisons, et dans la plupart des cas, vous en oublierez certaines.

Vous pourriez penser que l'héritage de classe est une bonne idée pour ce cas. Mais nous en avons juste besoin, pas plus.

C'est à ce moment que enum entre en jeu.


Utilisez enum type

En Java, les types enum sont des classes qui exportent une instance pour chaque constante d’énumération via un champ final statique public.

Ici, vous pouvez déclarer quatre constantes d’énumération: SPRING, SUMMER, FALL, WINTER. Chacun a son propre name.

public enum Season {
    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter");

    private String name;

    Season(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Revenons maintenant à la méthode.

public void printSeason(Season season) {
    System.out.println("It is " + season.getName() + " now!");
}

Au lieu d'utiliser int, vous pouvez maintenant utiliser Season comme entrée. Au lieu d'une vérification de condition, vous pouvez indiquer à Season de vous donner son nom.

Voici comment vous utilisez cette méthode maintenant:

printSeason(Season.SPRING);
printSeason(Season.WINTER);
printSeason(Season.WHATEVER); <-- compile error

Vous obtiendrez une erreur de compilation lorsque vous utiliserez une entrée incorrecte et vous obtiendrez une référence singleton non nulle de Season tant que le programme sera compilé.

Lorsque nous avons besoin d'une saison supplémentaire, nous ajoutons simplement une autre constante dans Season et pas plus.

public enum Season {
    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter"), 
    MYSEASON("My Season");

...

Chaque fois que vous avez besoin d'un ensemble fixe de constantes, enum peut être un bon choix (mais pas toujours). C'est une solution plus lisible, plus fiable et plus puissante.

45
Rangi Lin

Un type enum est un type dont les champs consistent en un ensemble fixe de constantes. Des exemples courants incluent les indications de la boussole (valeurs NORTH, SUD, EST et OUEST) et les jours de la semaine.

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

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.

Voici un code qui vous montre comment utiliser l'énumération Day définie ci-dessus:

public class EnumTest {
    Day day;

    public EnumTest(Day day) {
        this.day = day;
    }

    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;

            case FRIDAY:
                System.out.println("Fridays are better.");
                break;

            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;

            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }

    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(Day.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(Day.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(Day.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(Day.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

La sortie est:

Les lundis sont mauvais.
Les jours de semaine sont à peu près tout.
Les vendredis sont meilleurs.
Les week-ends sont les meilleurs.
Les week-ends sont les meilleurs.

Les types enum de langage de programmation Java sont beaucoup plus puissants que leurs homologues des autres langages. La déclaration enum définit une classe (appelée type enum). Le corps de la classe enum peut inclure des méthodes et d’autres champs. Le compilateur ajoute automatiquement des méthodes spéciales lorsqu'il crée une énumération. Par exemple, ils ont une méthode de valeurs statiques qui renvoie un tableau contenant toutes les valeurs de l'énum dans l'ordre dans lequel elles ont été déclarées. Cette méthode est couramment utilisée en combinaison avec la construction for-each pour parcourir les valeurs d'un type enum. Par exemple, ce code de l'exemple de la classe Planet ci-dessous itère sur toutes les planètes du système solaire.

for (Planet p : Planet.values()) {
    System.out.printf("Your weight on %s is %f%n",
                      p, p.surfaceWeight(mass));
}

En plus de ses propriétés et de son constructeur, Planet propose des méthodes permettant de récupérer la gravité de la surface et le poids d'un objet sur chaque planète. Voici un exemple de programme qui prend votre poids sur terre (dans n’importe quelle unité) et calcule et affiche votre poids sur toutes les planètes (dans la même unité):

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    Neptune (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    private double mass() { return mass; }
    private double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: Java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

Si vous exécutez Planet.class à partir de la ligne de commande avec un argument de 175, vous obtenez le résultat suivant:

$ Java Planet 175
Votre poids sur MERCURY est 66.107583
Votre poids sur VENUS est de 158,374842
Votre poids sur la Terre est 175.000000
Votre poids sur MARS est de 66.279007
Votre poids sur JUPITER est de 442.847567
Votre poids sur SATURN est 186.552719
Votre poids sur URANUS est de 158.397260
Votre poids sur Neptune est 199.207413

Source: http://docs.Oracle.com/javase/tutorial/Java/javaOO/enum.html

27
Ashraf Bashir

un Enum est un type sûr, vous ne pouvez donc pas affecter une nouvelle valeur à l'exécution. De plus, vous pouvez l'utiliser dans une instruction switch (comme un int).

2
Guillaume USE

Les langages de programmation Java enums sont beaucoup plus puissants que leurs homologues des autres langages, qui ne sont guère plus que des entiers glorifiés. La nouvelle déclaration enum définit une classe à part entière (appelée type enum). En plus de résoudre tous les problèmes (Not typesafe, No namespace, Brittleness and Printed values are uninformative) existant avec le modèle int Enum suivant utilisé avant Java 5.0:

public static final int SEASON_WINTER = 0;

cela vous permet également d'ajouter des méthodes et des champs arbitraires à un type enum, d'implémenter des interfaces arbitraires, etc. Les types Enum fournissent des implémentations de haute qualité de toutes les méthodes Object. Ils sont Comparable et Serializable, et le formulaire en série est conçu pour résister aux modifications arbitraires du type enum. Vous pouvez également utiliser Enum dans switch case.

Lisez l'article complet sur Java Enums http://docs.Oracle.com/javase/1.5.0/docs/guide/language/enums.html pour plus d'informations. détails.

0
Kuldeep Jain

Les énumérations sont les méthode recommandée pour fournir des noms faciles à retenir pour un ensemble défini de contants (éventuellement avec un comportement limité également).

Vous devriez utiliser des énumérations, sinon vous utiliseriez plusieurs constantes entières statiques (par exemple, public static int ROLE_ADMIN = 0 ou BLOOD_TYPE_AB = 2)

Les principaux avantages de l'utilisation d'énums au lieu de ceux-ci sont la sécurité de type, la compilation des avertissements/erreurs de type lors de l'utilisation de valeurs incorrectes et la fourniture d'un espace de noms pour les "constantes" associées. De plus, ils sont plus faciles à utiliser dans un IDE car cela aide aussi à compléter le code.

0
xea