Exprimer l'échec en Java

introduction

Il est étonnamment difficile d'exprimer un échec lorsqu'il s'agit de Java. Optionnel est apparu dans Java 8 et est devenu beaucoup plus facile à manipuler, mais il est toujours comparé à d'autres langages. J'ai été inquiet à ce sujet tous ces jours, alors voici un résumé de la façon dont je gère mes erreurs.

environnement

Java 8 ou version ultérieure (la version ultérieure est meilleure)

Gérer avec Null

En parlant de la route royale, c'est un motif qui renvoie Null s'il ne peut pas être obtenu. Jusqu'à ce que Optional apparaisse dans Java8, il était naturel de cocher Null, mais il semble que Optional ait changé. J'essaie de ne pas trop le traiter dans Null comme une valeur de retour dans l'application.

Je ne peux pas m'empêcher de laisser beaucoup d'anciens traitements, donc je les gère avec Null jusqu'au jour où ils pourront être refactorisés.

Main.java


public class Main {
    public static void main(String[] args) {
        String first = getFirstArg(args);
        if(first == null) {
            System.out.println("Il n'y a pas d'argument");
            return;
        }
        
        System.out.print("Le premier argument est[ " + first + "]est");
    }
    
    private static String getFirstArg(String[] args) {
        if(args == null || args.length == 0) {
            return null;
        }
        return args[0];
    }
}

Gérer avec booléen

C'est aussi une route royale. Je pense qu'il exprime souvent «est» a «peut». Dans ce cas, le type primitif «booléen» est souvent utilisé plutôt que le type d'objet «booléen». Puisqu'il peut être exprimé par "vrai" faux "au lieu de la présence ou de l'absence de données, ce contrôle est utilisé car il restera dans le futur.

Main.java


public class Main {
    public static void main(String[] args) {
        if(hasFirstArg(args)) {
            System.out.println("Il y a un argument");
        } else {
            System.out.println("Il n'y a pas d'argument");
        }
    }
    
    private static boolean hasFirstArg(String[] args) {
        return args != null && 0 < args.length;
    }
}

Express avec exception

Il est également possible d'exprimer une erreur en levant une exception. Si l'objectif de la méthode ne peut pas être atteint lorsque le processus est créé en tant que bibliothèque externe, il est utilisé, mais sinon il n'est pas beaucoup utilisé. S'il ne semble pas y avoir de problème, je le lance souvent par le bas et le jette tel quel, mais je fais attention à ne pas le jeter à la fin.

Je pense que c'est une expression difficile parce qu'elle est jetée ou quelque chose du genre, mais je veux bien l'utiliser. La difficulté est que le contrôle des erreurs est difficile, mais ...

Main.java


public class Main {
    public static void main(String[] args) {
        try {
            System.out.println("Le premier argument est[" + getFirstArg(args) + "]est");
        } catch(NullPointerException e) {
            System.out.println("L'argument est nul");
        } catch(IllegalArgumentException e) {
            System.out.println("Argument illégal");
        }
    }

    private static String getFirstArg(String[] args) {
        if(args == null) {
            throw new NullPointerException();
        }
        if(args.length == 0) {
            throw new IllegalArgumentException();
        }
        return args[0];
    }
}

Si vous publiez cela dans une critique, vous ne pourrez pas vous plaindre même si vous vous faites piquer.

Exprimé comme facultatif

Je pense que la fonction de base actuelle de Java est le standard exprimé par Optional qui est sorti plus tôt. La fonctionnalité est qu'il est facile de comprendre que cette valeur de retour peut ne pas exister à l'aide de Optional. Avec les expressions jusqu'à présent, il n'est pas possible de dire en un coup d'œil si cela a réussi ou échoué, et cela n'est pas connu tant que Null n'est pas vérifié, et si vous oubliez de vérifier Null et d'y accéder, tout le monde aime NullPointerException. Nous sommes très heureux de pouvoir sortir de cette situation avec l'avènement d'Optinal.

Pour plus de détails, veuillez consulter l'article sur Qiita. https://qiita.com/tasogarei/items/18488e450f080a7f87f3 https://qiita.com/tasogarei/items/f289d125660af6fe5ba6

Main.java


import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        Optional<String> arg = getFirstArg(args);
        arg.ifPresent(first ->System.out.print("Le premier argument est[ " + first + "]est"));
    }
    
    private static Optional<String> getFirstArg(String[] args) {
        if(args == null || args.length == 0) {
            return Optional.empty();
        }
        return Optional.ofNullable(args[0]);
    }
}

Cependant, comme Java 8 n'a pas ʻifPresentOrElse, il peut ne pas être possible d'exprimer le traitement quand il réussit et quand il échoue (apparu pour la première fois dans Java 9). Dans le cas de Java8, vous devez faire la triste chose de vérifier l'existence avec ʻis Present et d'écrire le processus avec ʻif`.

arg.ifPresentOrElse(first -> System.out.println("Le premier argument est[ " + first + "]est"),
            () -> System.out.println("Aucun argument"));

Alternativement, vous pouvez utiliser map etou Else (Get)pour convertir en un type spécifique pour le traitement. Il est plus difficile que vous ne le pensez de bien écrire cela, car en faire trop peut réduire la lisibilité dans Optional Nested Hell.

Main.java


import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        Optional<String> arg = getFirstArg(args);
        System.out.println(arg.map(first -> "Le premier argument est[" + first + "]est").orElse("Aucun argument"));
    }
    
    private static Optional<String> getFirstArg(String[] args) {
        if(args == null || args.length == 0) {
            return Optional.empty();
        }
        return Optional.ofNullable(args[0]);
    }
}

Express avec l'un ou l'autre

Avec l'avènement de Optional, il est devenu possible de rompre avec Null, mais Optional peut dire s'il a réussi ou échoué, mais ne peut pas en expliquer la raison. C'est là qu'intervient l'un ou l'autre.

L'un ou l'autre est pris en charge par le langage dans certains cas, mais malheureusement, il n'est pas pris en charge par Java. Bien que ce soit un niveau qui peut être implémenté par moi-même, il est implémenté dans une bibliothèque appelée vavr (il existe de nombreuses autres fonctions, mais cette fois je vais l'utiliser dans le but de l'un ou l'autre).

【officiel】 http://www.vavr.io/

Ajoutons donc une dépendance à pom.xml et implémentons-la.

pom.xml


    <dependency>
        <groupId>io.vavr</groupId>
        <artifactId>vavr</artifactId>
        <version>0.9.2</version>
    </dependency>

Main.java


import java.util.Optional;

import io.vavr.control.Either;

public class Main {
    public static void main(String[] args) {
        Either<Integer,String> arg = getFirstArg(args);
        if(arg.isRight()) {
            System.out.println("Le premier argument est[" + arg.get() + "]est");
        } else {
            System.out.println("Erreur d'argument. Type" + arg.getLeft());
        }
    }

    private static Either<Integer,String> getFirstArg(String[] args) {
        if(args == null) {
            return Either.left(1);
        }
        if(args.length == 0) {
            return Either.left(2);
        }
        return Either.right(args[0]);
    }
}

L'un ou l'autre réussit s'il y a une valeur dans Right et échoue s'il y a une valeur dans Left. Puisqu'il est permis d'avoir une valeur dans un seul d'entre eux, il n'y a pas de problème si vous pouvez confirmer lequel a la valeur.

Cependant, en Java, il n'y a pas de correspondance Scala, donc cela me rend triste d'exprimer lequel a une valeur avec if. Peut-être que vous pouvez faire quelque chose de similaire, mais je ne sais pas encore.

Cependant, il est maintenant possible d'exprimer le type d'échec, ce qui facilite la modification du processus, l'obtention de la valeur tout en exprimant l'erreur, etc.

finalement

Récemment, j'ai commencé à utiliser principalement Either avec Optional, et je l'implémente en me souciant de diverses choses. Il est difficile d'exprimer un échec, mais faites-moi savoir s'il existe une bonne méthode de mise en œuvre.

Recommended Posts

Exprimer l'échec en Java
Exprimez Java try-catch-finally avec scala.util.
Changements dans Java 11
Janken à Java
Taux circonférentiel à Java
FizzBuzz en Java
Lire JSON en Java
Faites un blackjack avec Java
Programmation par contraintes en Java
Mettez java8 dans centos7
NVL-ish guy en Java
Joindre des tableaux en Java
"Hello World" en Java
Interface appelable en Java
Commentaires dans la source Java
Fonctions Azure en Java
Formater XML en Java
Simple htmlspecialchars en Java
Hello World en Java
Utiliser OpenCV avec Java
Mémorandum WebApi avec Java
Détermination de type en Java
Exécuter des commandes en Java (ping)
Divers threads en java
Implémentation du tri de tas (en java)
API Zabbix en Java
POST JSON en Java
Créer JSON en Java
Manipulation de la date dans Java 8
Nouveautés de Java 8
Utiliser PreparedStatement en Java
Nouveautés de Java 9,10,11
Exécution parallèle en Java
Essayez d'utiliser RocksDB avec Java
Évitez l'erreur que Yuma a donnée en Java
Obtenir des informations EXIF en Java
Modifier ini en Java: ini4j
L'histoire de Java dans ce monde
Essayez d'appeler JavaScript en Java
Essayez le type fonctionnel en Java! ①
J'ai fait une roulette à Java.
Implémentation de l'authentification en deux étapes en Java
Refactoring: faire du Blackjack en Java
Analyse de sujets (LDA) en Java
Prétraitement NEologd en Java neologdn-java
Changer le codage Java dans Windows
API Java Stream en 5 minutes
Problème de ne pas trouver javax.annotation.Généré en Java 11
Lire l'entrée standard en Java
Implémenter l'authentification de base en Java
Rechercher un sous-ensemble en Java
[Java] Obtenir KClass en Java [Kotlin]
Créer des fonctions Azure en Java
Importer des données Excel avec Java
Implémenter une combinaison de mathématiques en Java
Construction de l'environnement JavaFX dans Java 13