Enum.valueOf

Voici un point rapide sur les enums et plus spécifiquement sur les méthodes valueOf et values.

Partons d’une enum simple :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public enum AnimalEnum {
 
    CHIEN("Wouaf"),  
    CHAT("Miaou"),  
    VACHE("Meuh"),  
    SERPENT("Kss");
 
    final private String onomatopee;
 
    AnimalEnum(String onomatopee) {
         this.onomatopee = onomatopee;
    }
 
    public String getOnomatopee() {
         return onomatopee;
    }
}

Vous noterez bien au passage que l’attribut « onomatopee » a été déclaré final et que ce n’est pas une erreur, à condition qu’il ne soit affecté que dans un seul constructeur.

Commençons avec la méthode values() qui renvoie toutes les enums disponibles dans notre enum :

1
2
3
4
5
6
7
8
9
10
@Test
public void testValues() {
    System.out.println(">>> testValues");
 
    final AnimalEnum[] values = AnimalEnum.values();
    for (AnimalEnum value : values) {
         System.out.println(value);
    }
    assertTrue("Taille", values.length == 4);
}

Continuons avec la méthode valueOf(). Elle permet de récupérer une enum en particulier en lui passant son nom :

1
2
3
4
5
6
7
8
9
10
@Test
public void testEnum() {
    System.out.println(">>> testEnum");
 
    final AnimalEnum chien = AnimalEnum.valueOf("CHIEN");
 
    final String onomatopee = chien.getOnomatopee();
    System.out.println(onomatopee + " " + onomatopee);
    assertEquals("Wouaf", onomatopee);
}

Bien entendu, il faut que le nom soit exact, faute de quoi on repart avec une exception :

1
2
3
4
5
6
7
8
@Test(expected = IllegalArgumentException.class)
public void testMauvaisNom() {
    System.out.println(">>> testMauvaisNom");
 
    // La valeur "Chat" n'est pas dans l'enum. On fallait demander "CHAT".
    final AnimalEnum chat = AnimalEnum.valueOf("Chat");
    System.out.println(chat);
}

Effectivement ce n’est pas super pratique. On peut réécrire valueOf mais, pour les besoins de cet email, disons simplement qu’on veut imiter String et proposer une méthode qui ignore la casse. Il faut donc compléter l’enum :

1
2
3
4
5
6
7
8
static AnimalEnum valueOfIgnioreCase(String name) throws IllegalArgumentException {
    try {
         return valueOf(name.toUpperCase());
    } catch (IllegalArgumentException e) {
         // Ici je prefere mon propre message.
         throw new IllegalArgumentException("La valeur " + name + " n'est pas disponible.");
    }
}

Et on peut tester comme suit :

1
2
3
4
5
6
7
8
9
10
@Test()
public void testMauvaisNomIgnoreCase() {
    System.out.println(">>> testMauvaisNomIgnoreCase");
 
    final AnimalEnum chat = AnimalEnum.valueOfIgnioreCase("Chat");
 
    final String onomatopee = chat.getOnomatopee();
    System.out.println(onomatopee + " " + onomatopee);
    assertEquals("Miaou", onomatopee);
}

Mais ce qui nous intéresse vraiment dans tout ça, ce sont les cris de nos animaux. La convention est de définir une méthode valueOfByFoo :

1
2
3
4
5
6
7
8
9
static AnimalEnum valueOfByOnomatopee(String onomatopee) throws IllegalArgumentException {
    for (AnimalEnum value : values()) {
         String onoma = value.getOnomatopee();
         if (onoma.equalsIgnoreCase(onomatopee)) {
              return value;
         }
    }
    throw new IllegalArgumentException("Le cri " + onomatopee + " n'est pas disponible.");
}

Et pour finir le test de la vache :

1
2
3
4
5
6
7
8
9
10
@Test
public void testOnomatopee() {
    System.out.println(">>> testOnomatopee");
 
    // Recherche avec une mauvaise case. Mais c'est pris en compte.
    final AnimalEnum vache = AnimalEnum.valueOfByOnomatopee("mEuh");
    final String onomatopee = vache.getOnomatopee();
    System.out.println(onomatopee + " " + onomatopee);
    assertEquals("Meuh", onomatopee);
}

C’est tout pour aujourd’hui. Une autre fois, on parlera des switchs sur les enums…

Laisser un commentaire