Accès rapide :
La vidéo
Définition d'un type énuméré simple
Association des états d'un type énuméré avec de valeurs numériques
Cette vidéo vous explique ce qu'est un type énuméré et comment en définir un en Java.
Un type énuméré est un type de données comportant en ensemble fini d'états (de valeurs). On donne à chaque état un nom, ce qui sera plus facile
à utiliser plutôt qu'une valeur numérique. Un type énuméré s'introduit avec le mot clé enum
. Conventionnellement, le nom du type
énuméré commence par une majuscule (tout comme pour une classe). De même, les noms des états sont écrits intégralement en majuscules et on
sépare chaque mot via un caractère _
(underscore). Voici un exemple de définition de type énuméré : il nous permettra de représenter
les états d'un feu tricolore de signalisation routière.
1 2 3 4 5 |
public enum Feu { VERT, ORANGE, ROUGE } |
D'une certaine manière, un type énuméré ressemble au type boolean
dans le sens ou l'ensemble des états connus pour le type est fini.
Comme pour une classe, un type énuméré est très souvent déclaré dans son propre fichier (ici Feu.java
) : si c'est bien le cas, alors
le mot clé public
est requis pour avoir accès à ce nouveau type de l'extérieur du fichier.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
public class Demo { // Pour permettre la saisie à partir de la console static BufferedReader keyboard = new BufferedReader( new InputStreamReader( System.in ) ); public static void main(String[] args) throws Exception { // La variable feu est basée sur notre type énuméré Feu feu = Feu.ORANGE; System.out.print( "Que voulez-vous faire (passer, attendre) : " ); String action = keyboard.readLine(); if ( action.equals( "passer" ) ) { // On compare les états du type énuméré if ( feu != Feu.VERT ) { System.out.println( "Vous ne pouvez pas passer, cas le feu n'est pas vert" ); } else { System.out.println( "Bonne route" ); } } else if ( action.equals( "attendre" ) ) { if ( feu == Feu.VERT ) { System.out.println( "Vous devez passer, les autres attendent derrière vous" ); } else { System.out.println( "Bonne initiative" ); } } else { System.out.println( "Commande inconnue" ); } } } |
Il est possible d'utiliser l'instruction switch
pour tester les différents états d'un type énuméré.
Nous reviendrons plus précisément sur l'instruction switch
dans le chapitre relatif aux instructions Java.
Pour l'heure, voici un exemple qui teste l'état d'une variable de type Feu
en utilisant cette instruction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Demo { public static void main(String[] args) throws Exception { Feu feu = Feu.ORANGE; switch ( feu ) { case VERT: System.out.println( "On peut passer" ); break; case ORANGE: System.out.println( "Attention..." ); break; default: System.out.println( "Faut absolument s'arréter !!!" ); } } } |
Il est important de ne pas oublier les break
à la fin de chaque cas, sans quoi l'exécution se poursuit au cas suivant.
Le bloc default
déclenche dans tous les autres cas, mais dans notre exemple, il ne reste qu'un seul cas non traité : si le feu est rouge.
Si vous programmez déjà en langage C, vous avez certainement cherché à comparer les types énumérés du langage Java
avec ceux du langage C. En fait, ces mécanismes sont franchement bien différents d'un langage à l'autre. En C, un type énuméré est un sous-ensemble
du type int
pour lequel chaque valeur numérique est associée à une constante : en C, on peut aussi bien utiliser la valeur numérique,
que la constante associée. Par contre en Java, cette association valeur numérique/état n'est pas intrinsèque au langage. Si vous cherchez à l'avoir,
il faudra l'implémenter de A à Z.
Je vous propose d'abord le code d'un type énuméré réalisant cette association, puis quelques explications suivront.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public enum Feu { VERT(0), ORANGE(1), ROUGE(2); private int value; private Feu( int value ) { this.value = value; } public int toInt() { return value; } public static Feu fromInt( int value ) { switch( value ) { case 0: return VERT; case 1: return ORANGE; default: return ROUGE; } } } |
Première chose à noter : en fait, un type énuméré est très proche d'une classe. Si vous souhaitez y ajouter des attributs ou des méthodes, il
ne faut pas oublier le ;
en ligne 3. Précédemment, il n'était pas utile, car seuls les états étaient spécifiés.
Chaque état sera, en réalité, une instance statique portée par le type énuméré. En fait, on aurait pu imaginer le code suivant : ce n'est plus un
enum
, mais une classe et les états sont définis sous formes d'attributs statiques. Vous en conviendrez certainement, la syntaxe
enum
n'est que du « sucre syntaxique » (afin d'adoucir la syntaxe Java).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class Feu { public static final Feu VERT = new Feu(0); public static final Feu ORANGE = new Feu(1); public static final Feu ROUGE = new Feu(2); private int value; private Feu( int value ) { this.value = value; } public int toInt() { return value; } public static Feu fromInt( int value ) { switch( value ) { case 0: return VERT; case 1: return ORANGE; default: return ROUGE; } } } |
Reprenons le code initial : il est donc nécessaire de maintenir la valeur numérique associée à chaque état sous forme d'attribut.
Notez bien que le constructeur est défini en private
: c'est important, sinon un utilisateur pourrait produire d'autres
états. Mais ne vous inquiétez pas trop, car si vous ne respectez pas ce point, le message d'erreur suivant sera produit lors de la compilation
de votre type énuméré.
$> javac Feu.java Feu.java:9: error: modifier public not allowed here public Feu( int value ) { ^ 1 error $>
Ensuite deux méthodes de passage « numérique -> état » et « état -> numérique » simplifieront les transitions. Le code suivant vous montre comment utiliser notre type énuméré.
1 2 3 4 5 6 7 8 9 10 11 |
public class Demo { public static void main( String [] args ) { Feu feu = Feu.ORANGE; int value = feu.toInt(); System.out.println( "ORANGE is associate to " + value ); System.out.println( "2 is associate to " + Feu.fromInt( 2 ) ); } } |
Pour finir, notez qu'en Java vous pouvez réaliser l'association des états avec autres choses que des valeurs numériques. Vous pouvez, par exemple, imaginer une association état/chaîne de caractères, ...
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :