123 votes

Convertir une chaîne de caractères en une valeur Enum équivalente

Est-il possible de convertir un String à une valeur équivalente dans un Enumeration en utilisant Java.

Je peux bien sûr le faire avec un grand if-else mais j'aimerais éviter cela si possible.

Compte tenu de cette documentation :

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Enumeration.html

Je n'ai pas beaucoup d'espoir que cela soit possible sans "ifs" ou "case statement".

260voto

adarshr Points 25912

J'espère que vous vous en rendez compte, java.util.Enumeration est différent de celui de Java 1.5 Enum types.

Vous pouvez simplement utiliser YourEnum.valueOf("String") pour obtenir le type d'enum équivalent.

Ainsi, si votre enum est défini comme suit :

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

Vous pouvez faire ceci :

String day = "SUNDAY";

Day dayEnum = Day.valueOf(day);

20voto

Xion Points 11130

En supposant que vous utilisiez les enums de Java 5 (ce qui n'est pas si sûr puisque vous mentionnez de vieux Enumeration ), vous pouvez utiliser la classe valueOf méthode de java.lang.Enum sous-classe :

MyEnum e = MyEnum.valueOf("ONE_OF_CONSTANTS");

9voto

AlexR Points 60796

Utiliser une méthode statique valueOf(String) défini pour chaque enum .

Par exemple, si vous avez enum MyEnum vous pouvez dire MyEnum.valueOf("foo")

6voto

advocate Points 577

Il se peut que j'aie trop élaboré ma propre solution sans me rendre compte que Type.valueOf("enum string") a réellement existé.

Je suppose que cela permet un contrôle plus granulaire, mais je ne suis pas sûr que ce soit vraiment nécessaire.

public enum Type {
    DEBIT,
    CREDIT;

    public static Map<String, Type> typeMapping = Maps.newHashMap();
    static {
        typeMapping.put(DEBIT.name(), DEBIT);
        typeMapping.put(CREDIT.name(), CREDIT);
    }

    public static Type getType(String typeName) {
        if (typeMapping.get(typeName) == null) {
            throw new RuntimeException(String.format("There is no Type mapping with name (%s)"));
        }
        return typeMapping.get(typeName);
    }
}

Je suppose que vous échangez IllegalArgumentException pour RuntimeException (ou toute autre exception que vous souhaitez lancer), ce qui pourrait potentiellement nettoyer le code.

0voto

MustardMan Points 43

Les autres réponses concernant l'utilisation de valueOf(string) sont justes, mais j'ajouterais que vous devriez protéger votre code contre la possibilité qu'une chaîne non valide soit transmise. Bien qu'aujourd'hui votre code ne transmette que des chaînes correspondant à des valeurs d'énumération valides, il est possible qu'une modification future de l'énumération ou une modification future d'autres parties de votre code (ou d'un code écrit par d'autres) rompe cette hypothèse.

Cela sera important dans des cas tels que l'écriture d'un setter pour une variable membre d'un enum d'une classe. Votre classe et son setter doivent se protéger eux-mêmes.

En JavaDocs pour Enum montrent qu'une exception pourrait être levée sur ce point ( IllegalArgumentException ou NullPointerException . Vous devez les traiter soit de manière générique, soit de manière spécifique. Les JavaDocs montrent également que cette fonction n'aime pas les "espaces blancs superflus" ... il faut donc envisager d'utiliser trim().

Je traiterais probablement les exceptions de manière générique, comme suit :

Enum BestEnumEver {OPTION_A, OPTION_B, OPTION_C}

// ... elsewhere in your code ...
// How confident are you that stringVar will have an acceptable value?
// How confident are you that the existing enum options will not need to change?
BestEnumEver enumValue;
try {
    // Consider using trim to eliminate extraneous whitespace
    enumValue = BestEnumEver.valueOf(stringVar.trim());
} catch (Exception e) {
    // handle the situation here. Here are a couple of ideas.
    // Apply null and expect the using code to detect.
    enumValue = null;
    // Have a defined private constant for a default value
    // assuming a default value would make more sense than null
    enumValue = DEFAULT_BEST_ENUM_EVER;
}

Mais vous pouvez aussi traiter chaque exception d'une manière unique.

Enum BestEnumEver {OPTION_A, OPTION_B, OPTION_C}

// ... elsewhere in your code ...
// How confident are you that stringVar will have an acceptable value?
// How confident are you that the existing enum options will not need to change?
BestEnumEver enumValue;
try {
    // Consider using trim to eliminate extraneous whitespace
    enumValue = BestEnumEver.valueOf(stringVar.trim());
} catch (IllegalArgumentException e1) {
    // handle the situation here ...
} catch (NullPointerException e2) {
    // handle the situation here ...
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X