juillet
2012
Que signifie une valeur nulle en Java ? C’est une question qui fait débat. Si une méthode, par exemple findDog(…), me renvoie null, cela veut-il dire qu’aucun chien n’a été trouvé ? Qu’une erreur s’est produite ? etc. Décidément les nuls continuent de faire parler d’eux. Et comme Google ne les aime pas, c’est Guava qui se charge de leur régler le compte à l’aide du wrapper Optional.
Pour illustrer le fonctionnement de ce wrapper, voici quelques tests unitaires qui me semblent assez parlant.
Commençons par le cas le plus simple :
1 2 3 4 5 6 7 8 | @Test public void testSimpleOptional() { // Arrange final Integer nb = 5; // Act Optional opt = Optional.of(nb); } |
Ici je construit mon wrapper à l’aide de la factory statique « of ». Une fois que c’est fait, j’ai accès à un ensemble de méthodes sur l’optional, dont la principale est « isPresent() » :
1 | assertTrue(opt.isPresent()); // true |
Ça me permet de vérifier que mon wrapper possède un contenu. Ensuite, je peux récupérer le-dit contenu.
1 | assertEquals(nb, opt.get()); // 5 == 5 : true |
Reprenons le test unitaire en entier :
1 2 3 4 5 6 7 8 9 10 11 12 | @Test public void testSimpleOptional() { // Arrange final Integer nb = 5; // Act Optional opt = Optional.of(nb); // Assert assertTrue(opt.isPresent()); assertEquals(nb, opt.get()); } |
Faisons la même chose avec un objet plus complexe, par exemple un chien.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Test public void testSimpleOptionalDog() { // Arrange final String name = "Milou"; final SimpleDog dog = new SimpleDog(name, ...); // Act Optional opt = Optional.of(dog); // Assert assertTrue(opt.isPresent()); assertEquals(name, opt.get().getName()); } |
La plupart du temps, on sera dans le cas présenté ci-dessus. Mais, de temps en temps, la méthode findDog proposée en introduction ne trouvera rien. Dans ce cas, je peux tout simplement créer un wrapper vide :
1 2 3 4 5 6 7 8 9 10 | @Test public void testAbsent() { // Arrange // Act Optional opt = Optional.absent(); // Assert assertFalse(opt.isPresent()); } |
Si toutefois, malgré l’indication de « non présence », on essaie d’accéder à la valeur, on va se manger une exception :
1 2 3 4 5 6 7 8 9 10 11 | @Test(expected = IllegalStateException.class) public void testAbsentISE() { // Arrange // Act Optional opt = Optional.absent(); // Assert assertFalse(opt.isPresent()); opt.get(); // ISE } |
Alors, je vous vois venir. C’est tout de même casse pied de devoir créer un wrapper vide. Mais que se passe-t-il lorsqu’on le crée avec une valeur nulle ? Bah une NPE bien entendu…
1 2 3 4 5 6 7 8 | @Test(expected = NullPointerException.class) public void testWithNull() { // Arrange final SimpleDog dog = null; // Act Optional opt = Optional.of(dog); // NPE } |
A la place de la factory « of », il faut utiliser « fromNullable » pour indique que le chien peut être null parfois :
1 2 3 4 5 6 7 8 9 10 11 | @Test public void testFromNull() { // Arrange final SimpleDog dog = null; // Act Optional opt = Optional.fromNullable(dog); // Assert assertFalse(opt.isPresent()); } |
Evidemment, on se mange de nouveau une ISE si on tente malgré tout d’accéder à la valeur, qui n’existe pas…
1 2 3 4 5 6 7 8 9 10 11 12 | @Test(expected = IllegalStateException.class) public void testFromNullButGet() { // Arrange final SimpleDog dog = null; // Act Optional opt = Optional.fromNullable(dog); // Assert assertFalse(opt.isPresent()); opt.get(); // ISE } |
La bonne pratique serait alors de demander une valeur de remplacement, dans le cas ou le contenu serait nul :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Test public void testFromNullAndGetOr() { // Arrange final SimpleDog dog = null; final String nomane = "noname"; // Act Optional opt = Optional.fromNullable(dog); // Assert assertFalse(opt.isPresent()); SimpleDog dog2 = opt.or(new SimpleDog(nomane, ...)); assertEquals(nomane, dog2.getName()); } |
Et voilà…
En complément, je vous conseille la lecture d’un article de Damien Gouyette, intitulé « Programmation fonctionnelle : utiliser le type Option dans les applications java d’aujourd’hui » et qui aborde le sujet sous un autre angle, excellent qui plus est
Commentaires récents
- Le Stop watch de Guava dans
- Le Stop watch de Guava dans
- Le Stop watch de Guava dans