Java Reference
In-Depth Information
We saw the Result object before. It is a cousin of the Optional type, in that it holds a value that may or
may not exist. However, the Result object will hold either the return value or an exception. These are the
only two options out of any non-void Java computation. The Result type, like the Optional type, can provide
a convenient API for accessing its contents.
We used the Result object before, but let's look at how such a type could be reimplemented now. What
we want is to store either a return value or an exception, which means that we can have two fields.
We expect only one of them to be null at any point in time; the other should be non-null. If you pass in a
return value, we call that a “successful” Result instance. If you pass in an exception, we call that a “failure”
Result instance. Since the type of the result and exception fields will depend on the caller's contexts, we will
make them type variables. In order to make for a nicer usage for the user, we can use static methods instead of
exposing constructors: the static methods trick the Java type system into doing more type inference work for
you, instead of having to repeat type information all over your code. We will also provide five accessors into
our state: two boolean accessors that just check if the result is successful or a failure; two direct accessors that
return the state of their field; and a combined accessor that returns the successful value if it is successful and
explodes with the failure value if it is a failure. Using this type, we can then implement our basic inline stream
error handling. The Result implementation and the error handling are demonstrated in Listing 7-6.
Listing 7-6. Handling Resources with a Result Type
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.stream.*;
public class Listing6 {
public static class Result<SUCCESS_T, FAILURE_T extends Exception> {
private final SUCCESS_T success;
private final FAILURE_T failure;
private Result(final SUCCESS_T success, final FAILURE_T failure) {
if (success == null && failure == null) {
throw new IllegalArgumentException(
"Success and failure cannot both be null");
}
if (success != null && failure != null) {
throw new IllegalArgumentException(
"Success and failure cannot both be non-null");
}
this.success = success;
this.failure = failure;
}
Search WWH ::




Custom Search