Accueil
Java Standard Edition
Java EE 5
Visual Basic .Net 2005
Visual C++ .Net 2005
Visual C# .Net 2005
Cours ASP .Net 2.0
Postgresql
Linux
Visual Studio 2008
ASP 3.0 Classique
Cours Javascript - DOM - DHTML
Cours Ajax
VBA
Assembleur
Perl
Membres
L'auteur du site
Nouveautés sur le site
Contacts
Plan du site
Exécution d'un programme
Les archives Jar
Les classes abstraites
Les interfaces
Les tableaux
La généricité
Les énumérations
Les classes internes
Classes anonymes et internes locales
Les threads: généralités
Les threads(2): synchronisation
E/S(1):InputStream et OutputStream
E/S(2):FileInputStream et FileOutputStream
E/S(3):Reader et Writer
E/S(4):FilterInputStream et FilterOutputStream
E/S(5):Les filtres d'octets: PrintStream
E/S(6):Les filtres d'octets: DataInputStream et DataOutputStream
E/S(7):Les filtres d'octets: BufferedInputStream et BufferedOutputStream
E/S(8):Flux de caractères: PrintWriter
E/S(9):Flux de caractères: FilterReader et FilterWriter
E/S(10):Flux de caractères: InputStreamReader, OutputStreamWriter, StreamDecoder, StreamEncoder
E/S(11):Flux de caractères: BufferedReader et BufferedWriter
E/S(12):Flux de caractères: FileReader et FileWriter
La classe String (java.lang)
Les collections: L'interface Collection(java.lang)
Les collections(2): L'interface List(java.util)
Les collections(3): AbstractCollection(java.util)
Les collections(4): AbstractList(java.util)
La bibliothèque Swing en Java
Les bases de données en Java
JDBC ( Java Database Connectivity )
Les interfaces graphiques
Les fichiers de configuration en Java
INSTALLATION JAVA EE 5, JRE 6, ECLIPSE, TOMCAT, ETC SOUS LINUX
INSTALLATION JAVA EE 5, JRE 6, ECLIPSE, TOMCAT, ETC SOUS WINDOWS
Les applications Web en java
Les filtres Java (javax.servlet.Filter)
I Généralités
I.1 Le formulaire principal
I.2 Les objets créés par Visual
I.3 Les variables références
I.4 Le garbage collector
II Créer évènements
II.1 Rappel évènements
II.2 Procédure à suivre
II.2.1 Créer son EventArgs
II.2.2 Créer EmetEvent
II.2.3 Déclarations autres
I Généralités
I.1 Applications winforms
I.2 Applications MFC
I.3 Objets managés ou pas
I.4 Objets non managés
I.5 Objets managés - handle
I.6 Le top-level ^
II Créer évènements
II.1 Rappel évènements
II.2 Procédure à suivre
II.2.1 Créer son EventArgs
II.2.2 Créer EmetEvent
II.2.3 Déclarations autres
I Généralités
I.1 Puissant et Accessible
I.2 Créer ses classes
II Créer évènements
II.1 Rappel évènements
II.2 Procédure à suivre
III Les services Windows
IV Le .net remoting
V Communication Tcp avec TcpClient et TcpListener
II.2.1 Créer son EventArgs
II.2.2 Créer EmetEvent
II.2.3 Déclarations autres
I Généralités
I.1 Un EDI formidable
I.2 Inclure C# ou VB
I.3 L'objet Response
I.4 Les évènements
II ASP .net et les bdd
II.1 Essayer plusieurs fois la requête
I 2.1 Fichiers distincts
I.2.2 Avec la balise script
I.2.3 Inclure réellement
I.2.4 Avec Response.Write()
I.3.1 La méthode Response.Redirect()
I.4.1 Résoudre problème post
Installation Postgre Linux
Cours Postgresql
Le Shell Unix( Linux, Ubuntu)
Les scripts C-Shell
Programmation système Unix
Reseau Linux
Les iptables
Windows Presentation Foundation(WPF)
Le Framework 3.0
Windows Workflow Foundation(WF)
ASP 3.0 Classique
Cours Javascript - DOM - DHTML
Chat Ajax
VBA Excel 2003
Assembleur
Perl
Inscription
Liste membres
Livre d'or
Forum
Accueil
>
Java Standard Edition
>
Les énumérations
____________________________________________________________________________________________________
Connexion
Java - Les énumérations
Sommaire :
I) Définition
II) Les méthodes des énumérations
III) La classe Enum
IV) Ajout de constructeurs, attributs et méthodes
V) Les énumérations "internes"
VI) Code source de java.lang.Enum
VII) Code source de l'exemple
VII-1) Classe Main (package main)
VII-2) Classe Voiture (package Vehicule)
VII-3) enum Couleurs (package main)
VIII)Téléchargement du projet d'exemple
I) Définition
- Possède beaucoup de points communs avec une classe( d'ailleurs nous verrons bientôt qu'une véritable classe est créée pour chaque énumération).
- On ne peut pas hériter d'un type enum.
Création:
package main; public enum Couleurs { rouge, vert, marron, orange, rose }
"Equivalent" à: (mais cette classe n'existe pas. Et ce n'est qu'un exemple possible d'implémentation)
public final class Couleurs { static { //static initializer qui initialiserait les propriétés statiques //au début, et une fois pour toutes this.rouge = new Couleurs("rouge", 0); this.vert = new Couleurs("vert", 1); this.marron = new Couleurs("marron", 2); this.orange = new Couleurs("orange", 3); this.rose = new Couleurs("rose", 4); } public static Couleurs rouge; //c'est bien public, car visible en dehors package public static Couleurs vert; public static Couleurs marron; public static Couleurs orange; public static Couleurs rose; //Attributs privés private int numOrdinal; private name; //Constructeur. Il est private private Couleurs(String pName, int pNumOrdinal) { this.name = pName; this.numOrdinal = pNumOrdinal; } //méthodes "héritées" public int ordinal() { //Retourne 0 si this = objet rouge, //1 si this = objet vert, etc return this.numOrdinal; } public String toString() { //Retourne la String "rouge" si this = objet rouge, //"vert" si this = objet "vert", etc, //donc retourne le nom de l'objet, dans une String return name; } //retourne un tableau contenant les 5 objets de type Couleurs public static Couleurs[] values() { (...) } (...) }
On crée l'énumération dans son propre fichier, comme pour les classes.
On peut également, comme pour les classes internes, déclarer une énumération à l'intérieur d'une classe(et comme pour les classes internes, la déclaration est alors suivie ou non d'un point-virgule).
On déclare nos valeurs d'énumération( rouge, vert, etc) en les séparant par des virgules. Chaque valeur est l'équivalent d'un attribut statique de la classe, comme on peut le vérifier en faisant l'aide à la frappe de Eclipse( "Couleurs."+ ctrl+espace, dans votre classe Main par exemple). Cet attribut est du type Couleurs, c'est comme un objet de type Couleurs, qui serait instancié à la première utilisation de la classe, dans un static initializer, et avec les bonnes valeurs correspondantes à la couleur en question.
Ces 5 objets Couleurs( Couleurs.rouge, Couleurs.vert, Couleurs.marron, Couleurs.orange et Couleurs.rose) sont les 5 uniques objets de la classe Couleurs qui pourront exister. On ne peut pas instancier d'autres objets de la classe Couleurs, hormis ceux créés à partir des valeurs de l'énumération. On ne peut pas faire new Couleurs(). D'ailleurs le constructeur new de notre classe fictive est en private, ce qui veut dire qu'on est autorisé à construire des objets à l'intérieur de la classe, mais pas à l'extérieur.
II) Les méthodes des énumérations
* C'est comme si notre "classe" disposait d'une méthode toString() qui retourne le nom de l'objet, dans une String.
* On dispose d'une méthode ordinal() qui retourne l'entier, à partir de zéro, correspondant à la position, dans l'énumération. Cette méthode pourrait être implémentée comme ci-dessus.
* Autres méthodes "héritées" dans la "classe" Couleurs, correspondante à notre énumération Couleurs:
la méthode values() retourne un Couleurs[] qui contient toutes les valeurs de l'énumération.
III) La classe Enum
- En réalité, pour chaque énumération, une classe, non accessible, est créée, et elle hérite de la classe abstraite java.lang.Enum. Elle a le nom de notre énumération.
Le code source de la classe Enum sera donné ci-dessous.
Le début de la classe est:
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable
C'est une classe abstraite, ne comportant pas de méthode déclarées avec le mot-clé abstract, et dont toutes les méthodes d'interface(en réalité il n'y en a qu'une) sont implémentées. Cette classe n'a, par conséquent, aucune méthode abstraite. Mais on ne peut pas l'instancier. C'est une classe générique, dont le paramètre de généricité doit être une classe héritant de Enum<cetteClasse>, ce qui est toujours le cas pour des classes d'énumérations, car elles sont déclarées, par exemple:
public class Couleurs extends Enum<Couleurs>
On en conlut qu'on a toujours E extends Enum<E> dans le cas de classes d'énumération.
Ceci apporte une garantie de ne pas pouvoir utiliser la classe générique Enum, avec un paramètre de généricité qui ne serait pas une énumération.
Rappelons que l'interface java.lang.Comparable est formée d'une seule méthode, compareTo. Et l'interface java.io.Serializable est vide.
- La classe mère des énumérations, la classe Enum, possède un attribut privé int ordinal, et un attribut privé String name. Elle a aussi la méthode toString( qui ne fait que retourner l'attribut name), et la méthode ordinal()( qui retourne l'attribut ordinal).
- La classe d'énumération créée possède une méthode statiques values(), qui n'est pas héritée de Enum, et qui retourne un tableau contenant l'ensemble des valeurs de l'énumération, par exemple public static Couleurs[] values() dans notre cas.
- La classe java.lang.Enum a une méthode equals(Object) qui compare deux valeurs d'énumération, et qui redéfinit la méthode equals de la classe Object:
/** * Returns true if the specified object is equal to this * enum constant. * * @param other the object to be compared for equality with this object. * @return true if the specified object is equal to this * enum constant. */ public final boolean equals(Object other) { return this==other; }
On apprend dans ce code qu'on peut également utiliser == pour tester l'égalité de deux valeurs d'énumération.
IV) Ajout de constructeurs, attributs et méthodes
IV-1) Ajout de constructeurs
- On peut rajouter des constructeurs à notre énumération. Reprenons notre exemple:
package main; public enum Couleurs { rouge("red"), vert("green"), marron("brown"), orange("orange"), rose("pink"); private String nomAnglais; //on ne peut mettre que le modificateur private pour les constructeurs //d'enum( même sans modificateur, c'est private) private Couleurs(String pNomAnglais) { this.nomAnglais = pNomAnglais; } public String getNomAnglais() { return this.nomAnglais; } }
Bien entendu, on ne peut toujours pas faire de new. Les constructeurs qu'on ajoute sont utilisés lors de la déclaration de l'énumération, ici dans la ligne "rouge("red"), vert("green"), marron("brown"), orange("orange"), rose("pink");".
Et ils sont forcément private(même sans mettre "private", ils le sont).
IV-2) Ajout d'attributs et méthodes
On peut également ajouter des attributs et des méthodes à notre énumération.
Tous ces membres qu'on ajoute(constructeurs, attributs, méthodes) sont bien sûr ajoutés à la classe équivalente non accessible.
Ici, dans la méthode main par exemple, en faisant:
System.out.println("Valeur de rouge.getNomAnglais():"+Couleurs.rouge.getNomAnglais());
Cela affiche "red"
IV-3) Ajout de méthodes static
- Il est possible de rajouter des méthodes static dans une énumération
Ajoutons à notre exemple d'enum Couleurs:
public static boolean isJeanAime( Couleurs pCoul) { switch (pCoul) { case rouge: case vert: case rose: return false; //pas besoin de break;, de toute façon compile pas avec break( //unreachable code) default: return true; } }
A noter qu'il est possible d'utiliser le switch pour les énumérations. Mais dans les valeurs de case, il faut respecter la syntaxe d'écrire juste la valeur enum, par exemple "rouge", et pas "Couleurs.rouge". Sinon il y a erreur de compilation("The enum constant reference Couleurs.rouge cannot be qualified in a case label"), car Couleurs.rouge est bien une référence. La syntaxe de mettre juste la valeur enum prouve bien au compilateur qu'on parle de la valeur(qui est sûrement la valeur de ordinal() d'ailleurs). Le compilateur sait de quelle énumération on parle grâce au type de l'objet mis dans le switch. L'écriture "rouge"(tout seul) n'est jamais autorisé hormis ce cas, car rappelons que rouge est normalement un attribut static de la classe Couleurs.
Rappelons que le switch n'accepte normalement que des valeurs entières ou char. Ici le compilateur doit certainement se débrouiller en remplaçant l'objet dans le switch avec sa valeur ordinal(), et en remplaçant la valeur dans les cases par le ordinal correspondant. Il se retrouve alors avec un switch classique de valeurs entières! Il aurait été dommage d'interdire les switch de valeurs enum, ce qui est particulièrement utile.
V) Les énumérations "internes"
- Revoyons plus précisément sur le cas où l'énumération est interne à une classe:
public class Main { public enum Nombres { //si en private, accessible seulement à l'intérieur //de la classe Main un, deux, trois, quatre }; // ; n'est pas obligatoire /** * @param args */ public static void main(String[] args) { (...) Main.Nombres monNombre = Main.Nombres.deux; // on accède à l'énumération Nombres comme si c'était un membre statique de //Main. Nombres est juste un type, pas comme les attributs habituels //qui sont des valeurs(objets ou pas). Et c'est un type comme n'importe //quel type, sauf qu'on y accède à partir du nom de la classe(on peut //jamais écrire Nombres, mais toujours Main.Nombres, même à l'intérieur //de la classe). System.out.println("Valeur de monNombre(qui vaut 2):"+monNombre); } }
On accède à l'énumération Nombres comme si c'était un membre statique de Main. Nombres est juste un type, pas comme les attributs habituels qui sont des valeurs(objets ou pas). Et c'est un type comme n'importe quel type, sauf qu'on y accède à partir du nom de la classe(on peut jamais écrire Nombres, mais toujours Main.Nombres, même à l'intérieur de la classe).
C'est le principe des classes internes, mais statiques. On ne peut pas avoir une énumération interne qui ne soit pas static. D'ailleurs on peut ajouter le mot-clé static: public static enum(...). Cela veut dire qu'on ne peut pas appeler des attributs d'instance de la classe englobante, dans des éventuelles méthodes de l'énumération.
Bien sûr, on peut utiliser l'énumération à l'extérieur de la classe, et même du package. Comme le montre l'exemple ci-dessous. Mais si l'énumération avait été déclarée en private, on n'y accèderait que dans la classe englobante.
package vehicule; /** * Classe de test uniquement * @author sabri * */ public final class Voiture { private main.Couleurs maCoul = main.Couleurs.orange; //on accède aux membres //de Couleurs même en dehors du package public int retourneDeux() { main.Main.Nombres monNombre = main.Main.Nombres.deux; //on accède //à l'énumération monNombre même en dehors du package return monNombre.ordinal()+1; } }
VI) Code source de java.lang.Enum
- Voici le code source de Enum:
/* * @(#)Enum.java 1.15 06/01/27 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.lang; import java.io.Serializable; /** * This is the common base class of all Java language enumeration types. * * @author Josh Bloch * @author Neal Gafter * @version 1.15, 01/27/06 * @since 1.5 */ public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { /** * The name of this enum constant, as declared in the enum declaration. * Most programmers should use the {@link #toString} method rather than * accessing this field. */ private final String name; /** * Returns the name of this enum constant, exactly as declared in its * enum declaration. * * <b>Most programmers should use the {@link #toString} method in * preference to this one, as the toString method may return * a more user-friendly name.</b> This method is designed primarily for * use in specialized situations where correctness depends on getting the * exact name, which will not vary from release to release. * * @return the name of this enum constant */ public final String name() { return name; } /** * The ordinal of this enumeration constant (its position * in the enum declaration, where the initial constant is assigned * an ordinal of zero). * * Most programmers will have no use for this field. It is designed * for use by sophisticated enum-based data structures, such as * {@link java.util.EnumSet} and {@link java.util.EnumMap}. */ private final int ordinal; /** * Returns the ordinal of this enumeration constant (its position * in its enum declaration, where the initial constant is assigned * an ordinal of zero). * * Most programmers will have no use for this method. It is * designed for use by sophisticated enum-based data structures, such * as {@link java.util.EnumSet} and {@link java.util.EnumMap}. * * @return the ordinal of this enumeration constant */ public final int ordinal() { return ordinal; } /** * Sole constructor. Programmers cannot invoke this constructor. * It is for use by code emitted by the compiler in response to * enum type declarations. * * @param name - The name of this enum constant, which is the identifier * used to declare it. * @param ordinal - The ordinal of this enumeration constant (its position * in the enum declaration, where the initial constant is assigned * an ordinal of zero). */ protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } /** * Returns the name of this enum constant, as contained in the * declaration. This method may be overridden, though it typically * isn't necessary or desirable. An enum type should override this * method when a more "programmer-friendly" string form exists. * * @return the name of this enum constant */ public String toString() { return name; } /** * Returns true if the specified object is equal to this * enum constant. * * @param other the object to be compared for equality with this object. * @return true if the specified object is equal to this * enum constant. */ public final boolean equals(Object other) { return this==other; } /** * Returns a hash code for this enum constant. * * @return a hash code for this enum constant. */ public final int hashCode() { return super.hashCode(); } /** * Throws CloneNotSupportedException. This guarantees that enums * are never cloned, which is necessary to preserve their "singleton" * status. * * @return (never returns) */ protected final Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } /** * Compares this enum with the specified object for order. Returns a * negative integer, zero, or a positive integer as this object is less * than, equal to, or greater than the specified object. * * Enum constants are only comparable to other enum constants of the * same enum type. The natural order implemented by this * method is the order in which the constants are declared. */ public final int compareTo(E o) { Enum other = (Enum)o; Enum self = this; if (self.getClass() != other.getClass() && // optimization self.getDeclaringClass() != other.getDeclaringClass()) throw new ClassCastException(); return self.ordinal - other.ordinal; } /** * Returns the Class object corresponding to this enum constant's * enum type. Two enum constants e1 and e2 are of the * same enum type if and only if * e1.getDeclaringClass() == e2.getDeclaringClass(). * (The value returned by this method may differ from the one returned * by the {@link Object#getClass} method for enum constants with * constant-specific class bodies.) * * @return the Class object corresponding to this enum constant's * enum type */ public final Class<E> getDeclaringClass() { Class clazz = getClass(); Class zuper = clazz.getSuperclass(); return (zuper == Enum.class) ? clazz : zuper; } /** * Returns the enum constant of the specified enum type with the * specified name. The name must match exactly an identifier used * to declare an enum constant in this type. (Extraneous whitespace * characters are not permitted.) * * @param enumType the <tt>Class</tt> object of the enum type from which * to return a constant * @param name the name of the constant to return * @return the enum constant of the specified enum type with the * specified name * @throws IllegalArgumentException if the specified enum type has * no constant with the specified name, or the specified * class object does not represent an enum type * @throws NullPointerException if <tt>enumType</tt> or <tt>name</tt> * is null * @since 1.5 */ public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) { T result = enumType.enumConstantDirectory().get(name); if (result != null) return result; if (name == null) throw new NullPointerException("Name is null"); throw new IllegalArgumentException( "No enum const " + enumType +"." + name); } /** * enum classes cannot have finalize methods. */ protected final void finalize() { } }
VII) Code source de l'exemple
VII-1) Classe Main (package main)
package main; import vehicule.Voiture; /** * * @author sabri Koffler pour www.infkoffler.com, exemple du cours Java Standard * @version 1.1 (de l'application) / 26/10/2008 * Créé 23/10/2008 * Exemple d'utilisation des énumérations * en Java * * Classe Main créée uniquement pour la méthode main * */ public class Main { public enum Nombres { //si en private, accessible seulement à l'intérieur //de la classe Main un, deux, trois, quatre; public void methTest() { //Main.this.methDeMain(); Erreur de compilation: l'énumération est //forcément static, je ne peux pas accéder à this de la classe //englobante ("No enclosing instance of the type main is //accessible in scope"), comme dans une classe interne non static } }; // ; n'est pas obligatoire /** * @param args */ public static void main(String[] args) { //affiche "rouge": la méthode toString() construit une string correspondante au nom System.out.println("Valeur de rouge.toString() = *"+Couleurs.rouge.toString()+"*"); System.out.println("Valeur de rouge.getNomAnglais():"+Couleurs.rouge.getNomAnglais()); System.out.println("Valeur de Couleurs.isJeanAime(Couleurs.vert):"+Couleurs.isJeanAime(Couleurs.vert)); System.out.println("Valeur de Couleurs.isJeanAime(Couleurs.marron):"+Couleurs.isJeanAime(Couleurs.marron)); // Main.Nombres monNombre = Main.Nombres.deux; // on accède à l'énumération Nombres comme si c'était un membre statique de //Main. Nombres est juste un type, pas comme les attributs habituels //qui sont des valeurs(objets ou pas). Et c'est un type comme n'importe //quel type, sauf qu'on y accède à partir du nom de la classe(on peut //jamais écrire Nombres, mais toujours Main.Nombres, même à l'intérieur //de la classe). System.out.println("Valeur de monNombre(qui vaut 2):"+monNombre); } }
VII-2) Classe Voiture (package Vehicule)
package vehicule; /** * * @author sabri Koffler * Exemple d'utilisation des énumérations * en Java * Classe de test uniquement */ public final class Voiture { private main.Couleurs maCoul = main.Couleurs.orange; //on accède aux membres //de Couleurs même en dehors du package public int retourneDeux() { main.Main.Nombres monNombre = main.Main.Nombres.deux; //on accède //à l'énumération monNombre même en dehors du package return monNombre.ordinal()+1; } }
VII-3) enum Couleurs (package main)
package main; /** * * @author sabri Koffler * Exemple d'utilisation des énumérations * en Java * */ public enum Couleurs { rouge("red"), vert("green"), marron("brown"), orange("orange"), rose("pink"); private String nomAnglais; //on ne peut mettre que le modificateur private pour les constructeurs //d'enum( même sans modificateur, c'est private) private Couleurs(String pNomAnglais) { this.nomAnglais = pNomAnglais; } public String getNomAnglais() { return this.nomAnglais; } public static boolean isJeanAime( Couleurs pCoul) { switch (pCoul) { case rouge: case vert: case rose: return false; //pas besoin de break;, de toute façon compile pas avec break( //unreachable code) default: return true; } } }
VIII)Téléchargement du projet d'exemple
Projet d'exemple, V1.1
RETOUR HAUT