Express failure in Java

Introduction

It's surprisingly difficult to express failure when dealing with Java. Optional has appeared in Java 8 and it has become much easier to handle, but it is still compared to other languages. I've been worried about it all these days, so here's a summary of how I handle my own mistakes.

environment

Java 8 or later (later version is better)

Handle with Null

Speaking of the royal road, it is a pattern to return Null if it can not be acquired. Until Optional appeared in Java8, it was natural to check Null, but it seems that Optional has changed. I try not to treat it too much in Null as a return value in the application.

I can't help but leave a lot of old processing, so I handle it with Null until the day when it can be refactored.

Main.java


public class Main {
    public static void main(String[] args) {
        String first = getFirstArg(args);
        if(first == null) {
            System.out.println("There are no arguments");
            return;
        }
        
        System.out.print("The first argument is[ " + first + "]is");
    }
    
    private static String getFirstArg(String[] args) {
        if(args == null || args.length == 0) {
            return null;
        }
        return args[0];
    }
}

Handle with Boolean

This is also a royal road. I think it often expresses ʻis has can. In this case, the primitive type boolean is often used rather than the Object type Boolean. Since it can be expressed by true``false` instead of the presence or absence of data, this check is used as it will remain in the future.

Main.java


public class Main {
    public static void main(String[] args) {
        if(hasFirstArg(args)) {
            System.out.println("There are arguments");
        } else {
            System.out.println("There are no arguments");
        }
    }
    
    private static boolean hasFirstArg(String[] args) {
        return args != null && 0 < args.length;
    }
}

Express with Exception

It is also possible to express an error by raising an exception. If the purpose of the method cannot be achieved when the process is created as an external library, it is used, but otherwise it is not used much. If it doesn't seem to be a problem, I often throw it from the bottom and throw it as it is, but I'm careful not to throw it away in the end.

I think it's a difficult expression because it's thrown away or something, but I want to use it well. The difficulty is that error control is difficult, but ...

Main.java


public class Main {
    public static void main(String[] args) {
        try {
            System.out.println("The first argument is[" + getFirstArg(args) + "]is");
        } catch(NullPointerException e) {
            System.out.println("Argument is null");
        } catch(IllegalArgumentException e) {
            System.out.println("Illegal argument");
        }
    }

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

If you put this out in a review, you won't be able to complain even if you get stung.

Expressed as Optional

I think that expressing with Optional that came out earlier is standard if it is the current basic function of Java. The feature is that it is easy to understand that this return value may not exist by using Optional. With the expressions so far, it is not possible to tell at a glance whether it is successful or unsuccessful, and it is not known until Null is checked, and if you forget to check Null and access it, everyone will love NullPointerException. We are very pleased to be able to get out of this situation with the advent of Optinal.

For details, I have published an article on Qiita, so please have a look there. 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("The first argument is[ " + first + "]is"));
    }
    
    private static Optional<String> getFirstArg(String[] args) {
        if(args == null || args.length == 0) {
            return Optional.empty();
        }
        return Optional.ofNullable(args[0]);
    }
}

However, since ʻifPresentOrElse does not exist in Java8, it may not be possible to express the processing when it succeeds and when it fails (first appeared in Java9). In the case of Java8, you have to do the sad thing of checking the existence with ʻis Present and writing the process with ʻif`.

arg.ifPresentOrElse(first -> System.out.println("The first argument is[ " + first + "]is"),
            () -> System.out.println("No arguments"));

Alternatively, you can use map and ʻor Else (Get)` to convert to a specific type for processing. Overdoing it can reduce readability in Optional Nest Hell, so it's harder than you think to write it well.

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 -> "The first argument is[" + first + "]is").orElse("No arguments"));
    }
    
    private static Optional<String> getFirstArg(String[] args) {
        if(args == null || args.length == 0) {
            return Optional.empty();
        }
        return Optional.ofNullable(args[0]);
    }
}

Express with Either

With the advent of Optional, it has become possible to break away from null, but Optional can tell whether it succeeded or failed, but cannot explain why. That's where Either comes in.

Either is supported in some languages, but unfortunately it is not supported in Java. Although it is a level that can be implemented by myself, it is implemented in a library called vavr (there are many other functions, but this time I will use it for Either purpose).

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

So let's add a dependency to pom.xml and implement it.

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("The first argument is[" + arg.get() + "]is");
        } else {
            System.out.println("Argument error. 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]);
    }
}

Either is successful if there is a value in Right and fails if there is a value in Left. Since it is allowed to have a value in only one of them, there is no problem if you can confirm which one has the value for success or failure.

However, in Java, there is no such thing as a Scala match, so it makes me sad to express which one has a value with if. Maybe you can do something similar to match, but I don't know yet.

However, now it is possible to express the type of failure, which makes it easy to change the process, get the value while expressing the error, and so on.

Finally

Recently, I've started using Either mainly with Optional, and I'm implementing it while worrying about various things. It's difficult to express failure, but please let me know if there is a good implementation method.

Recommended Posts

Express failure in Java
Express Java try-catch-finally in Scala's scala.util.Try
Changes in Java 11
Rock-paper-scissors in Java
Pi in Java
FizzBuzz in Java
[java] sort in list
Read JSON in Java
Make Blackjack in Java
Constraint programming in Java
Put java8 in centos7
NVL-ish guy in Java
Combine arrays in Java
"Hello World" in Java
Callable Interface in Java
Comments in Java source
Azure functions in java
Format XML in Java
Simple htmlspecialchars in Java
Hello World in Java
Use OpenCV in Java
webApi memorandum in java
Type determination in Java
Ping commands in Java
Various threads in java
Heapsort implementation (in java)
Zabbix API in Java
POST JSON in Java
Create JSON in Java
Date manipulation in Java 8
What's new in Java 8
Use PreparedStatement in Java
What's new in Java 9,10,11
Parallel execution in Java
Initializing HashMap in Java
Try using RocksDB in Java
Avoid Yubaba's error in Java
Get EXIF information in Java
Save Java PDF in Excel
Edit ini in Java: ini4j
Java history in this world
Try calling JavaScript in Java
Try functional type in Java! ①
I made roulette in Java.
Create hyperlinks in Java PowerPoint
Implement two-step verification in Java
Refactoring: Make Blackjack in Java
Topic Analysis (LDA) in Java
NEologd preprocessing in Java neologdn-java
Change java encoding in windows
Java Stream API in 5 minutes
Cannot find javax.annotation.Generated in Java 11
Read standard input in Java
Implement Basic authentication in Java
Find a subset in Java
[Java] Get KClass in Java [Kotlin]
Create Azure Functions in Java
Import Excel data in Java
Implement math combinations in Java
JavaFX environment construction in Java 13
Insert footer in Java Powerpoint