Java中的功能样式错误处理

除了使用异常处理错误的经典方法外,还可以区分功能方法。

可以立即将其本地化,然后对其执行某些操作,而不是立即引发异常。

例如,在Scala中,为此使用了特定的Try类。

def inputStreamForURL(url: String): Try[Try[Try[InputStream]]] = parseURL(url).map { u => Try(u.openConnection()).map(conn => Try(conn.getInputStream)) } 

在Java世界中,使用Vavr库,您还可以按功能样式处理错误。

 Try.of(() -> u.openConnection()).getOrElse(other); 

在Java 8中,添加了Optional类以更正确地使用null类型。 它允许您包装一个可以为null的对象,并且以函数样式可以安全地进行进一步处理。

要使用不同类型的异常,可以实现类似于Optional的类,该类也是线程安全且不稳定的。

 public final class Expected<T, E extends Throwable> { private final T value; private final E error; private Expected() { this.value = null; this.error = null; } private Expected(T value) { this.value = Objects.requireNonNull(value); this.error = null; } private Expected(E error) { this.error = Objects.requireNonNull(error); this.value = null; } public static <T, E extends Throwable> Expected<T, E> of(T value) { return new Expected<>(value); } public static <T, E extends Throwable> Expected<T, E> of(E error) { return new Expected<>(error); } public static <T, E extends Throwable> Expected<T, E> of(Supplier<T> supplier) { try { return new Expected<>(supplier.get()); } catch (Throwable e) { return new Expected<>((E) e); } } public boolean isValue() { return value != null; } public boolean isError() { return error != null; } public T value() { return value; } public E error() { return error; } } 

另外,要检查是否引发了异常,您可以编写一个简单的访问者。

 Expected<Integer, SQLException> data = Expected.of(new SQLException()); matches(data, Expected::error, e -> out.println("get error: " + e), Expected::value, v -> out.println("get value: " + v) ); Expected<Integer, ArithmeticException> expression = Expected.of(() -> 4 / 0); matches(expression, Expected::error, e -> out.println("get error: " + e), Expected::value, v -> out.println("get value: " + v) ); 

 public static <T, E extends Throwable> void matches(Expected<T, E> value, Function<Expected<T, E>, E> firstFunction, Consumer<E> firstBranch, Function<Expected<T, E>, T> secondFunction, Consumer<T> secondBranch) { if (value.isError()) { E arg = firstFunction.apply(value); firstBranch.accept(arg); } else { T arg = secondFunction.apply(value); secondBranch.accept(arg); } } 

在C ++ 23中,计划向标准库添加一个类似的类。

这样的类可以在标准Java库中构成优秀的Optional公司。 但是,现在,要以功能性样式处理异常,您可以使用Vavr库或以Expected的方式编写自己的类。

该类的完整源代码可以在github: link上查看。

Source: https://habr.com/ru/post/zh-CN469329/


All Articles