[JAVA] N'utilisez pas `get ()` ~ Loser Facultatif

Quand j'ai regardé les articles sur Java Optional, j'ai vu beaucoup de gens dire: "Dans cette méthode d'enseignement, il n'y aura que ceux qui utilisent ** Optional de manière totalement floue ...", donc au moins j'ai lu cet article en rébellion. écrire.

TL; DR

Pour ceux qui ne connaissent que ʻis Present () et get () `

yamero.png

N'écris pas comme ça

En regardant l'article

null La vérification est effectuée avec ʻOptional # isPresent () , et la valeur est récupérée avec ʻOptional # get ().

Il y a trop d'explications comme.

** Ne faites pas ça **. Alors ** rien n'est différent du contrôle nul conventionnel **. Au lieu de changer, le nombre de types a augmenté, le temps d'exécution a augmenté, l'utilisation de la mémoire a augmenté **, et seuls les inconvénients ont été ajoutés **. Je n'ai aucun mérite.

Optional<String> someStr = Optional.of("Hello, world!");

if (someStr.isPresent()) {
    System.out.println(someStr.get()); //Ne fais pas ça
}

La première chose à laquelle je veux que vous pensiez est que vous ne devriez pas utiliser ** ʻOptional # get () `**.

C'est important, alors je le répète.

** ʻNe pas utiliser facultatif # get () `**. </ span>

ʻOptional # get () `est ** une méthode de type merde pour récupérer sans se soucier de savoir si elle est nulle ou non **. C'est ** dangereux **. Il est préparé en ** uniquement ** pour "quand vous devez l'utiliser quand même".

<! - "C'est bon parce que j'ai vérifié null juste avant" ou quelque chose comme ça, ** Antony Hoare reviendra sur cet article après que le cul se soit fait enculer **. Si "ça va parce que je vérifie null", ** la méthode conventionnelle suffit **. C'est ** sans signification **. Vous pouvez utiliser ** ʻOptional # get () `même si vous oubliez de cocher ** null. ** Et crash **. C'est une histoire idiote. ->

Le gars qui saute "Je vais bien parce que je vérifie null juste avant" ** Je reviendrai sur cet article après avoir été en colère contre Antony Hoare **. Si "ça va parce que je vérifie null", ** la méthode conventionnelle suffit **. C'est ** sans signification **. Vous pouvez utiliser ** ʻOptional # get () `même si vous oubliez de cocher ** null. ** Et crash **. C'est une histoire idiote.

Alors que devons-nous faire. ** ʻUtiliser facultatif # ifPresent () `**. Cette méthode prend une référence de méthode comme argument. Donc, je vais écrire l'expression lambda à l'intérieur ... ** Vous pouvez l'écrire comme ça sans connaître l'expression lambda ou la référence de la méthode **.

Optional<String> someStr = Optional.of("Hello, world!");

someStr.ifPresent(x -> {
    System.out.println(x);
});

ʻLa référence de méthode passée à Optional # ifPresent () ʻest exécutée seulement quand elle n'est pas ** null **. Vous pouvez considérer x comme une ** variable temporaire **. Bien sûr, le nom est gratuit (sauf si vous le portez). Le type est naturellement T pour ʻOptional `. Il est préférable de connaître les expressions lambda et les références de méthodes, mais même si vous ne le connaissez pas, cela devrait suffire car cela ressemble à une instruction if normale **.

Il peut y avoir des cas où vous ne souhaitez pas exécuter uniquement lorsqu'il n'est pas nul, mais vous souhaitez séparer les actions en fonction de la présence ou de l'absence d'une valeur **.

Optional<String> someStr = Optional.empty();

if (someStr.isPresent()) {
    System.out.println(someStr.get()); //Bien sûr, ne le fais pas
} else {
    System.out.println("Il n'y avait aucune valeur");
}

Dans ce cas, utilisez ** ʻOptional # ifPresentOrElse () `**.

Optional<String> someStr = Optional.empty();

someStr.ifPresentOrElse(x -> {
    System.out.println(x);
}, () -> {
    System.out.println("Il n'y avait aucune valeur");
});

() -> ... signifie une expression lambda sans argument, mais bien sûr, vous pouvez la considérer comme "une magie quand vous n'utilisez pas de valeur".

Notez que ʻOptional # ifPresentOrElse () `a été implémenté dans Java 9, donc dans un environnement Java 8

Optional<String> someStr = Optional.empty();

someStr.ifPresent(x -> {
    System.out.println(x);
}); if (!someStr.isPresent()) {
    System.out.println("Il n'y avait aucune valeur");
}

Il n'y aura pas d'autre choix que de.

N'utilisez pas ʻOptional # ifPresent () `autant que possible

** Si possible, ʻOptional # ifPresent () ne doit pas non plus être abusé **. ʻOptional # map () , ʻOptional # flatMap ()et ʻOptional # orElse ()devraient souvent être suffisants. Dans le monde d'Optionnel, il est basique ** qu'il n'y ait pas de ** vérification nulle.

Par exemple, l'exemple de ʻOptional # ifPresentOrElse () mentionné ci-dessus peut être écrit de manière plus concise en utilisant ces méthodes. Si vous utilisez ʻOptional # orElse () pour déballer en spécifiant une valeur de remplacement quand il était ʻempty`,

Optional<String> someStr = Optional.empty();

System.out.println(someStr.orElse("Il n'y avait aucune valeur"));

C'est bon. Et si ʻOptional au lieu de ʻOptional <String>? Alors il est temps pour ʻOptional # map () d'appliquer la fonction uniquement quand elle n'est pas ʻempty.

Optional<Integer> someInt = Optional.empty();

System.out.println(someInt.map(x -> x.toString()).orElse("Il n'y avait aucune valeur"));

Il peut être rédigé de manière plus concise si vous étudiez les références de méthodes.

Optional<Integer> someInt = Optional.empty();

System.out.println(someInt.map(Object::toString).orElse("Il n'y avait aucune valeur"));

Bien sûr, si vous pensez qu'une ligne est longue, vous pouvez définir une variable à l'extérieur et la retirer.

Voir cet article pour des exemples plus divers.

Il y a trop de perdants et des articles pour les perdants sont écrits

Comme il existe de nombreux articles de commentaires autoproclamés qui produisent des perdants, ʻOptional # get () `n'est pas utilisé en premier lieu, ou la partie de base de base selon laquelle il est idéal de ne pas vérifier null lui-même n'est pas bien connue, il vaut donc mieux ne pas avoir Facultatif »sera écrit dans un ** article ironique **.

  • Remplacez «NullPointerException» par «NoSuchElementException». Le programme plantera toujours.

Si myOPoint ne contient pas les coordonnées réelles, myOPoint.get (). X lance NoSuchElementException et plante le programme. Ce n'est rien de mieux que le code original. Parce que le but du programmeur est d'éviter tous les plantages, pas seulement les plantages provoqués par NullPointerException.

Encore une fois, les deux codes sont similaires et «Optionnel» n'est pas supérieur aux méthodes de référence traditionnelles.

soreha.jpg

Eh bien, l'auteur de cet article a probablement écrit un tel article parce qu'il y avait trop de perdants. ~~ Pourtant, il y a des descriptions qu'il n'en sait rien. ~~

Un exemple où vous devrez peut-être utiliser ʻOptional # get () `

En raison des spécifications, ** les traitements pouvant entraîner des exceptions ne peuvent pas être traités à l'extérieur **.

public static int half(int even) throws Exception {
    if (even % 2 == 0); else {
        throw new Exception();
    }
    
    return even / 2;
}

/* ... */

Optional<Integer> someInt = Optional.of(16);

/*ça peut*/
try {
    if (someInt.isPresent()) {
        System.out.println(half(someInt.get()));
    }
} catch (Exception e) {
    System.out.println("Veuillez passer un pair");
}

/*Ne peux pas*/
try {
    someInt.ifPresent(x -> {
        System.out.println(half(x));
    });
} catch (Exception e) {
    System.out.println("Veuillez passer un pair");
}

Afin de gérer cela, divers hacks sont introduits dans Qiita. Je pense que cela peut être géré en utilisant l'un ou l'autre. C'est Monad. Eh bien, Java n'est pas officiellement non plus.

Recommended Posts

N'utilisez pas `get ()` ~ Loser Facultatif
N'utilisez pas le nombre magique ...
Comment utiliser java Facultatif
Point 26: N'utilisez pas de types bruts
Comment utiliser HttpClient de Java (Get)