[JAVA] À propos d'énumération

Qu'est-ce que l'énumération

Type d'énumération. Classe d'énumération. En interne, une classe qui hérite de la classe java.lang.Enum. [^ 1]

[^ 1]: L'héritage de java.lang.Enum est effectué par le compilateur. Le programmeur ne peut pas hériter explicitement de la classe.

Pour plus d'informations sur enum, consultez le chapitre 6 du livre "Effective Java". L'auteur, Joshua Bloch, est le responsable des spécifications pour JSR 201.

Problèmes résolus par enum

Avant enum

Au départ, les déclarations de constantes destinées uniquement à la distinction étaient décrites dans le modèle int enum [^ 2].

CalendarConst.java


public final static int JANUARY = 0;
public final static int FEBRUARY = 1;
public final static int MARCH = 2;
public final static int APRIL = 3;
public final static int MAY = 4;
public final static int JUNE = 5;
public final static int JULY = 6;
public final static int AUGUST = 7;
public final static int SEPTEMBER = 8;
public final static int OCTOBER = 9;
public final static int NOVEMBER = 10;
public final static int DECEMBER = 11;
public final static int UNDECIMBER = 12;

Le modèle int enum était efficace pour empêcher les nombres magiques d'apparaître, mais avait les problèmes suivants.

  1. Aucune garantie de type Puisqu'il s'agit d'un int, il est possible de faire des descriptions dénuées de sens, comme passer une valeur int non pertinente si nécessaire ou ajouter deux constantes.

  2. Il n'y a pas d'espace de noms Vous devez faire précéder la constante d'une chaîne pour éviter tout conflit avec d'autres types d'énumération int.

  3. Vulnérabilité L'énumération int est une constante de compilation. Si une nouvelle constante est ajoutée entre deux constantes existantes ou si l'ordre est modifié, le client doit être recompilé. Si vous ne le compilez pas, vous pouvez l'exécuter, mais le comportement est imprévisible.

  4. La valeur de sortie n'a pas de valeur d'information Toutes les sorties sont numériques. Je ne sais pas ce que cela signifie, et je ne sais même pas quel est son type.

[^ 2]: Actuellement, c'est un anti-pattern.

Tapez un modèle d'énumération sûre

Le modèle d'énumération de type sécurisé résout le problème du modèle d'énumération int. Les constantes d'énumération sont fournies dans une classe Singleton.

MonthEnum.java


public class MonthEnum {

    private final String name;
    private final int ordinal;

    private Month(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    public String name() {
        return name;
    }

    public int getValue()
    {
        return ordinal() + 1;
    }

    public String toString() {
        return name;
    }

    public static final Month JANUARY = new Month("JANUARY", 0);
    public static final Month FEBRUARY = new Month("FEBRUARY", 1);
    public static final Month MARCH = new Month("MARCH", 2);
    public static final Month APRIL = new Month("APRIL", 3);
    public static final Month MAY = new Month("MAY", 4);
    public static final Month JUNE = new Month("JUNE", 5);
    public static final Month JULY = new Month("JULY", 6);
    public static final Month AUGUST = new Month("AUGUST", 7);
    public static final Month SEPTEMBER = new Month("SEPTEMBER", 8);
    public static final Month OCTOBER = new Month("OCTOBER", 9);
    public static final Month NOVEMBER = new Month("NOVEMBER", 10);
    public static final Month DECEMBER = new Month("DECEMBER", 11);
}

Il s'agit de la méthode de description standard avant l'avènement de enum (avant Java 5).

enum Dans Java5 ou version ultérieure, la classe enum (type d'énumération) peut être utilisée.

Month.java



public enum Month {

    JANUARY,
    FEBRUARY,
    MARCH,
    APRIL,
    MAY,
    JUNE,
    JULY,
    AUGUST,
    SEPTEMBER,
    OCTOBER,
    NOVEMBER,
    DECEMBER;

    public int getValue() {
        return ordinal() + 1;
    }

}

Bien qu'il s'agisse d'une brève description, il s'agit en principe d'une extension du modèle d'énumération de type sécurisé. Vous pouvez confirmer que le modèle d'énumération de type sécurisé est appliqué en recompilant le fichier de classe qui compile la classe enum. Le résultat de la compilation inverse est illustré ci-dessous.

Month.jad


public final class Month extends Enum
{

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

    public int getValue()
    {
        return ordinal() + 1;
    }

    public static Month[] values()
    {
        Month amonth[];
        int i;
        Month amonth1[];
        System.arraycopy(amonth = ENUM$VALUES, 0, amonth1 = new Month[i = amonth.length], 0, i);
        return amonth1;
    }

    public static Month valueOf(String s)
    {
        return (Month)Enum.valueOf(g06_enum/Month, s);
    }

    public static final Month JANUARY;
    public static final Month FEBRUARY;
    public static final Month MARCH;
    public static final Month APRIL;
    public static final Month MAY;
    public static final Month JUNE;
    public static final Month JULY;
    public static final Month AUGUST;
    public static final Month SEPTEMBER;
    public static final Month OCTOBER;
    public static final Month NOVEMBER;
    public static final Month DECEMBER;
    private static final Month ENUM$VALUES[];

    static 
    {
        JANUARY = new Month("JANUARY", 0);
        FEBRUARY = new Month("FEBRUARY", 1);
        MARCH = new Month("MARCH", 2);
        APRIL = new Month("APRIL", 3);
        MAY = new Month("MAY", 4);
        JUNE = new Month("JUNE", 5);
        JULY = new Month("JULY", 6);
        AUGUST = new Month("AUGUST", 7);
        SEPTEMBER = new Month("SEPTEMBER", 8);
        OCTOBER = new Month("OCTOBER", 9);
        NOVEMBER = new Month("NOVEMBER", 10);
        DECEMBER = new Month("DECEMBER", 11);
        ENUM$VALUES = (new Month[] {
            JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, 
            NOVEMBER, DECEMBER
        });
    }
}

Il s'agit d'une classe Singleton qui hérite de la classe Enum en appliquant le modèle d'énumération de type sécurisé. Les valeurs et méthodes valueOf, ENUM $ VALUES, etc. sont automatiquement générées par le compilateur. [^ 3]

[^ 3]: Le getValue que j'ai créé plus tôt est une méthode d'instance, mais values et valueOf sont des méthodes de classe de la classe Month.

Que pouvez-vous faire avec enum

Définition du constructeur avec arguments

Month.java


public enum Month {

    JANUARY(1),
    FEBRUARY(2),
    MARCH(3),

    private int monthNumber;

    private Month(int param) {
        monthNumber = param;
    }
}

Il est compilé comme suit.

Month.jad


public final class Month extends Enum
{
    private Month(String s, int i, int param)
    {
        super(s, i);
        monthNumber = param;
    }

    public static Month[] values(){/*réduction*/}

    public static Month valueOf(String s){/*réduction*/}

    public static final Month JANUARY;
    public static final Month FEBRUARY;
    public static final Month MARCH;
    private int monthNumber;
    private static final Month ENUM$VALUES[];

    static 
    {
        JANUARY = new Month("JANUARY", 0, 1);
        FEBRUARY = new Month("FEBRUARY", 1, 2);
        MARCH = new Month("MARCH", 2, 3);
        ENUM$VALUES = (new Month[] {
            JANUARY, FEBRUARY, MARCH
        });
    }
}

Utilisation de la classe Enum

Puisqu'il a une relation d'héritage avec la classe java.lang.Enum, Enum API peut être utilisé. ..

Recommended Posts

À propos d'énumération
À propos =
À propos de method.invoke
À propos de Kotlin
À propos de attr_accessor
À propos de Hinemos
À propos de l'héritage
À propos de Docker
À propos du printemps ③
À propos du polymorphisme
À propos facultatif
À propos du hachage
À propos de JitPack
À propos de ça ()
À propos de l'encapsulation
[Java] enum (type d'énumération)
À propos de JAVA_HOME
À propos de statique
À propos des exceptions
À propos de la portée
[Maven] À propos de Maven
À propos de la gestion des exceptions
À propos de l'interface Java
[Java] À propos des fonctionnalités de Java 12
À propos du routage des rails
À propos de la complexité cyclique
Enum (type d'énumération)
À propos de la gestion des exceptions
À propos des symboles Ruby
À propos de la multiplication des tableaux
[Java] À propos des tableaux
À propos de l'héritage de classe.
À propos de Spring AOP
À propos de Ruby Hash
À propos des méthodes singulières
À propos des outils de création
Note de révision Enum
Mâchez l'API
[À propos du double hachage]
Quelque chose à propos de java
Où est Java
À propos de la méthode de HttpServlet ()
À propos des fonctionnalités Java