Java 8: Exception Handling

According to Oracle1, Java SE 8 class called java.util.Optional<T> that is inspired from the ideas of Haskell and Scala. In the functional programming, exceptions are side effects and need to avoid.

Optional in a Nutshell

The Optional class includes methods to explicitly deal with the cases where a value is present or absent. You can create variable Optional<Something> sc = Optional.empty() or Optional<Something> sc = Optional.ofNullable(Something); for null object. Otherwise the Optional<Something> sc = Optional.of(Something) create the Something object.

Patterns of using Optional

This blog is the summary of the video2 I went through. The problem is very simply demonstrated in the following code:

package au.com.blogspot.ojitha.trainings.exception;


import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class ExExample {
    public static void main(String[] args) {
        Stream.of("a.txt", "b.txt","c.txt")
                .flatMap(f -> Files.lines(Paths.get(f)))
                .forEach(r -> System.out.println());
    }
}

In the line number 11, you get an java.io.IOException which need to be handled otherwise you cannot compile above code.

Here, the very straight forward solutions: handle the exception in side the flatmap.

public class ExExample {

    public static void main(String[] args) {
        Stream.of("a.txt", "b.txt","c.txt")
                .flatMap(f -> {
                    try {
                        return Files.lines(Paths.get(f));
                    } catch (IOException ioe){
                       return Stream.empty();
                    }

                })
                .forEach(r -> System.out.println());
    }
}

The more elegant solution is to create a wrapper which will handle the exception as follows:

package au.com.blogspot.ojitha.trainings.exception;


import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;

@FunctionalInterface
interface ExFunction<E, F> {
    F apply (E e) throws Throwable;
    static <E, F> Function<E, Optional<F>> wrap (ExFunction<E, F> op){
        return e -> {
            try {
                return Optional.of(op.apply(e));
            } catch (Throwable throwable) {
                return Optional.empty();
            }
        };
    }

}

public class ExExample {

    public static void main(String[] args) {
        Stream.of("a.txt", "b.txt","c.txt")
                .map(ExFunction.wrap(f -> Files.lines(Paths.get(f))))
                .filter(opt -> opt.isPresent()) //filter only the available files
                .flatMap(opt -> opt.get())
                .forEach(r -> System.out.println(r));
    }
}

Line 10-23 shows the wrapper function which is generic. This generic function return Optional.empty() for the element which raised the exception. When this applied to the practical situation (such as line 29), you can filter only the best cases to flow with the success path as shown in the line 30.

REFERENCE:


  1. Tired of Null Pointer Exceptions? Consider Using Java SE 8's "Optional"! 

  2. Modern Java Exception Handling October 12, 2018, SIMON ROBERTS, O`reillly. 

Comments

Popular posts from this blog

How To: GitHub projects in Spring Tool Suite

Spring 3 Part 7: Spring with Databases

Parse the namespace based XML using Python