Writing exception handling is always a hassle, so I arranged it a little.
Method that raises a checked exception
void raiseIOEx1(String s) throws IOException {
if (s.equals("nagare")) {
System.out.println("Excellent!");
return;
}
throw new IOException("invalid input :".concat(s));
}
It's a rough idea, but when there is a method like the one above (aside from why IOException?)
Normal writing
void usually_try_style() {
try {
raiseIOEx1("nagare");
} catch (IOException e) {
e.printStackTrace();
}
}
Arranged writing style
void nagare_try_style() {
Try.throwable(this::raiseIOEx1)
.ifCatch(IOException::printStackTrace)
.accept("nagare");
}
You can write like this.
Also, in the case of a method that returns a value, you can write as follows.
Method 2 that raises a checked exception
String raiseIOEx2(String s) throws IOException {
if (s.equals("nagare")) {
return "Excellent!";
}
throw new IOException("invalid input :".concat(s));
}
Normal writing
void usually_returnable_try_style() {
try {
String s = raiseIOEx2("nagare");
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
}
Arranged writing style
void nagare_returnable_try_style() {
Optional<String> s = Try.throwable(this::raiseIOEx2)
.ifCatch(IOException::printStackTrace)
.apply("nagare");
s.ifPresent(System.out::println);
// or
Try.throwable(this::raiseIOEx2)
.ifCatch(IOException::printStackTrace)
.apply("nagare");
.ifPresent(System.out::println);
}
It is not recommended to use it at the business level, but the above description can be made by adding the following 4 classes.
public class Try {
public static <X, A, E extends Exception> ThrowableFunc<X, A, E> throwable(
ThrowableFunc<X, A, E> f) {
return f;
}
public static <X, E extends Exception> ThrowableSpender<X, E> throwable(
ThrowableSpender<X, E> s) {
return s;
}
}
@FunctionalInterface
public interface ThrowableSpender<X, E extends Exception> {
void accept(X x) throws E;
default Consumer<X> ifCatch(ExHandler<E> handler) {
return (X x) -> {
try {
accept(x);
} catch (Exception e) {
@SuppressWarnings("unchecked")
E typedE = (E) e; // is type safe
handler.handle(typedE);
}
};
}
}
@FunctionalInterface
public interface ThrowableFunc<X, A, E extends Exception> {
A apply(X x) throws E;
default Function<X, Optional<A>> ifCatch(ExHandler<E> handler) {
return x -> {
try {
return Optional.of(apply(x));
} catch (Exception e) {
@SuppressWarnings("unchecked")
E typedE = (E) e; // is type safe
handler.handle(typedE);
}
return Optional.empty();
};
}
}
@FunctionalInterface
public interface ExHandler<E extends Exception> {
void handle(E e);
}
As you can see by reading the code, I'm a little cheating at catch
.
try {
accept(x);
} catch (E e) {
handler.handle(e);
}
If you can write like this, you will be able to write multiple exceptions only with the interface, which seems to make a lot of progress, but it's a shame. I hope you can write in java9.
https://github.com/mt-village/nagare
-How to handle exceptions coolly with Stream and Optional of Java8
Recommended Posts