Lors de la programmation, nous rencontrons souvent le besoin de limiter l'ensemble des valeurs valides pour un certain type de données. Ainsi, par exemple, le jour de la semaine peut avoir 7 valeurs différentes, le mois de l'année peut en avoir 12 et la saison peut en avoir 4. Pour résoudre de tels problèmes, de nombreux langages de programmation à typage statique fournissent un type de données spécial - énumération ( Les membres Enum sont des instances
Les éléments
enum
). L'énumération n'est pas apparue immédiatement en Java. Une construction de langage spécialisée enum
a été introduite à partir de la version 1.5. Jusqu'à présent, les programmeurs ont utilisé d'autres méthodes pour implémenter les énumérations.
construction enum
Commençons par un exemple.enum
Décrivons le type de données pour stocker la période de l'année en utilisant :
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
Eh bien, un exemple simple de son utilisation :
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
À la suite de quoi SUMMER sera imprimé sur la console . Je pense que l'exemple est évident et n'a pas besoin d'explication.
Enum est une classe
En déclarantenum
, nous créons implicitement une classe dérivée de java.lang.Enum
. Classiquement, la construction enum Season { ... }
équivaut à class Season extends java.lang.Enum { ... }
. Et bien que le compilateur ne nous permet pas d'hériter explicitement de java.lang.Enum
nous, il est toujours facile de vérifier qu'il enum
est hérité en utilisant reflection
:
System.out.println(Season.class.getSuperclass());
Les éléments suivants seront affichés sur la console :
class java.lang.Enum
L'héritage proprement dit est automatiquement effectué pour nous par le compilateur Java. Ensuite, convenons d'appeler la classe créée par le compilateur pour implémenter l'énumération la enum
-class, et les valeurs possibles du type énuméré en tant enum
qu'éléments -a.
Les membres Enum sont des instances enum
d'une classe qui sont accessibles statiquement
Les éléments enum Season (WINTER, SPRING и т.д.)
sont des instances accessibles statiquement enum
de la -class Season
. Leur disponibilité statique nous permet d'effectuer des comparaisons à l'aide de l'opérateur de comparaison de référence ==
. Exemple:
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
Nom et numéro de série de l'élément enum
Comme mentionné précédemment, touteenum
-class hérite de java.lang.Enum
, qui contient un certain nombre de méthodes utiles pour toutes les énumérations. Exemple:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
Le résultat sera :
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
Les méthodes name()
, toString()
et sont présentées ici ordinal()
. La sémantique des méthodes est évidente. Il convient de noter que ces méthodes enum
sont héritées de la classe java.lang.Enum
. Obtenir un élément enum
par la représentation sous forme de chaîne de son nom Très souvent, la tâche consiste à obtenir un élément enum
par sa représentation sous forme de chaîne. À ces fins, dans chaque enum
classe, le compilateur crée automatiquement une méthode statique spéciale : public static EnumClass valueOf(String name)
, qui renvoie un élément d'énumération EnumClass
avec un nom égal à name
. Exemple d'utilisation :
String name = "WINTER";
Season season = Season.valueOf(name);
Suite à l'exécution du code, la variable de saison sera égale à Season.WINTER
. Veuillez noter que si l'élément n'est pas trouvé, une IllegalArgumentException sera levée , et s'il est name
égal null
, une NullPointerException sera levée . D’ailleurs, cela est souvent oublié. Pour une raison quelconque, beaucoup sont fermement convaincus que si une fonction prend un argument et, dans certaines conditions, lève une IllegalArgumentException , alors en la passant là-bas , une IllegalArgumentExceptionnull
sera certainement également lancée . Mais ce n’est pas la question. Nous allons continuer. Obtenir tous les éléments d'une énumération Parfois, vous avez besoin d'obtenir une liste de tous les éléments d'une -class au moment de l'exécution. À ces fins, le compilateur crée une méthode dans chaque -class . Exemple d'utilisation : enum
enum
public static EnumClass[] values()
System.out.println(Arrays.toString(Season.values()));
Nous obtenons le résultat suivant :
[WINTER, SPRING, SUMMER, AUTUMN]
Notez que ni la méthode valueOf()
ni la méthode values()
ne sont définies dans la classe java.lang.Enum
. Au lieu de cela, ils sont automatiquement ajoutés par le compilateur lorsque enum
la classe est compilée. Ajouter vos propres méthodes à enum
la -classe Vous avez la possibilité d'ajouter vos propres méthodes à la fois à la enum
-classe et à ses éléments : Les mêmes, mais avec un polymorphisme : Le dernier exemple démontre l'utilisation de l'héritage dans enum
. Nous en reparlerons plus tard. L'héritageenum
en Java enum
vous permet d'implémenter une hiérarchie de classes dont les objets sont créés en une seule instance et sont accessibles statiquement. Dans ce cas, les éléments enum
peuvent contenir leurs propres constructeurs. Donnons un exemple : ici nous déclarons une énumération Type
avec trois éléments INT
, INTEGER
et STRING
. Le compilateur créera les classes et objets suivants :
Type
- classe dérivée dejava.lang.Enum
INT
— objet de 1ère classe dérivé deType
INTEGER
— objet de 2ème classe dérivé deType
STRING
— objet de 3ème classe dérivé deType
Object parse(String)
et un constructeur polymorphes Type(..., boolean)
. Dans le même temps, les objets des classes INT
, INTEGER
et STRING
existent en un seul exemplaire et sont accessibles statiquement. Vous pouvez vérifier ceci :
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass() + " " + Type.STRING.getClass().getSuperclass());
Nous obtenons le résultat suivant :
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
On peut voir que le compilateur a créé une classe Type
et 3 nested
classes dérivées de Type
.
Classe enum décompilée avec héritage
Pour confirmer ce qui précède, nous présentons également le résultat de la décompilation de l'énumérationType
à partir de l'exemple ci-dessus :
Énumérations et polymorphisme paramétrique
Le lecteur peut se demander : « Pourquoi l’énumération de types ci-dessus n’utilise-t-elle pas de génériques ? » Le fait est qu'en Java, l'utilisation de génériques estenum
interdite. L'exemple suivant ne sera donc pas compilé :
enum Type<T> {}
Une étude plus approfondie
Pour une compréhension plus approfondie du fonctionnement des énumérations en Java, je vous recommande de vous familiariser avec le code source de la classejava.lang.Enum
et d'utiliser également le décompilateur Jad pour étudier le code généré. De plus, l’étude du code source de la bibliothèque Java est absolument nécessaire pour comprendre combien de mécanismes Java fonctionnent et constitue une référence utile pour la conception orientée objet. Lien vers la source originale : http://alexander.lds.lg.ua/
GO TO FULL VERSION