一种以功能方式处理异常的更好方法

一种以功能方式处理异常的更好方法,第1张

一种以功能方式处理异常的更好方法

下面显示的是

Exceptional
该类的完整代码。它具有相当大的API,是对
Optional
API 的纯扩展,因此可以在任何现有代码中直接替换它-
除非它不是最终
Optional
类的子类型。这个类可以被看作是与相同的关系是
Try
因为单子
Optional
是与
Maybe
单子:它的设计灵感来自它,但是适应了Java的成语(如实际抛出异常,甚至从非终端 *** 作)。

这些是班级遵循的一些关键准则:

  • 与monadic方法相反,它不会忽略Java的异常机制;

  • 相反,它可以消除异常和高阶函数之间的阻抗不匹配;

  • 异常处理不是静态的类型安全(由于偷偷摸摸的抛出),但是在运行时始终是安全的(除明确请求外,绝不吞咽异常)。

该类尝试涵盖处理异常的所有典型方法:

  • recover
    带有一些提供替代值的处理代码;
  • flatRecover
    类似于
    flatMap
    ,它允许返回一个新
    Exceptional
    实例,该实例将被解包并适当更新当前实例的状态;
  • propagate
    异常,将其从
    Exceptional
    表达式中抛出,并使
    propagate
    调用声明此异常类型;
  • propagate
    包装到另一个异常后( 翻译 );
  • handle
    它,导致一个空的
    Exceptional
  • 作为处理的一种特殊情况,
    swallow
    它带有一个空的处理程序块。

propagate
方法允许一个人有选择地从他的代码中选择他想公开哪些检查过的异常。在调用终端 *** 作时仍未处理的异常(如
get
)将被不加声明地
偷偷
抛出。这通常被认为是一种先进且危险的方法,但是仍然经常被用作某种方式,以与未声明它们的lambda形状相结合,在某种程度上减轻受检查的异常的滋扰。该
Exceptional
班希望能提供一个更清洁,更具有选择性替代偷偷摸摸扔。


import java.util.NoSuchElementException;import java.util.Objects;import java.util.function.Consumer;import java.util.function.Function;import java.util.function.Predicate;import java.util.function.Supplier;public final class Exceptional<T>{  private final T value;  private final Throwable exception;  private Exceptional(T value, Throwable exc) {    this.value = value;    this.exception = exc;  }  public static <T> Exceptional<T> empty() {    return new Exceptional<>(null, null);  }  public static <T> Exceptional<T> ofNullable(T value) {    return value != null ? of(value) : empty();  }  public static <T> Exceptional<T> of(T value) {    return new Exceptional<>(Objects.requireNonNull(value), null);  }  public static <T> Exceptional<T> ofNullableException(Throwable exception) {    return exception != null? new Exceptional<>(null, exception) : empty();  }  public static <T> Exceptional<T> ofException(Throwable exception) {    return new Exceptional<>(null, Objects.requireNonNull(exception));  }  public static <T> Exceptional<T> from(TrySupplier<T> supplier) {    try {      return ofNullable(supplier.tryGet());    } catch (Throwable t) {      return new Exceptional<>(null, t);    }  }  public static Exceptional<Void> fromVoid(TryRunnable task) {    try {      task.run();      return new Exceptional<>(null, null);    } catch (Throwable t) {      return new Exceptional<>(null, t);    }  }  public static <E extends Throwable> Consumer<? super E> swallow() {    return e -> {};  }  public T get() {    if (value != null) return value;    if (exception != null) sneakyThrow(exception);    throw new NoSuchElementException("No value present");  }  public T orElse(T other) {    if (value != null) return value;    if (exception != null) sneakyThrow(exception);    return other;  }  public T orElseGet(Supplier<? extends T> other) {    if (value != null) return value;    if (exception != null) sneakyThrow(exception);    return other.get();  }  public Stream<T> stream() {       return value == null ? Stream.empty() : Stream.of(value);   }  public<U> Exceptional<U> map(Function<? super T, ? extends U> mapper) {    Objects.requireNonNull(mapper);    if (value == null) return new Exceptional<>(null, exception);    final U u;    try {      u = mapper.apply(value);    } catch (Throwable exc) {      return new Exceptional<>(null, exc);    }    return ofNullable(u);  }  public<U> Exceptional<U> flatMap(Function<? super T, Exceptional<U>> mapper) {    Objects.requireNonNull(mapper);    return value != null ? Objects.requireNonNull(mapper.apply(value)) : empty();  }  public Exceptional<T> filter(Predicate<? super T> predicate) {    Objects.requireNonNull(predicate);    if (value == null) return this;    final boolean b;    try {      b = predicate.test(value);    } catch (Throwable t) {      return ofException(t);    }    return b ? this : empty();  }  public <X extends Throwable> Exceptional<T> recover(      Class<? extends X> excType, Function<? super X, T> mapper)  {    Objects.requireNonNull(mapper);    return excType.isInstance(exception) ? ofNullable(mapper.apply(excType.cast(exception))) : this;  }  public <X extends Throwable> Exceptional<T> recover(      Iterable<Class<? extends X>> excTypes, Function<? super X, T> mapper)  {    Objects.requireNonNull(mapper);    for (Class<? extends X> excType : excTypes)      if (excType.isInstance(exception))        return ofNullable(mapper.apply(excType.cast(exception)));    return this;  }  public <X extends Throwable> Exceptional<T> flatRecover(      Class<? extends X> excType, Function<? super X, Exceptional<T>> mapper)  {    Objects.requireNonNull(mapper);    return excType.isInstance(exception) ? Objects.requireNonNull(mapper.apply(excType.cast(exception))) : this;  }  public <X extends Throwable> Exceptional<T> flatRecover(      Iterable<Class<? extends X>> excTypes, Function<? super X, Exceptional<T>> mapper)  {    Objects.requireNonNull(mapper);    for (Class<? extends X> c : excTypes)      if (c.isInstance(exception))        return Objects.requireNonNull(mapper.apply(c.cast(exception)));    return this;  }  public <E extends Throwable> Exceptional<T> propagate(Class<E> excType) throws E {    if (excType.isInstance(exception))      throw excType.cast(exception);    return this;  }  public <E extends Throwable> Exceptional<T> propagate(Iterable<Class<? extends E>> excTypes) throws E {    for (Class<? extends E> excType : excTypes)      if (excType.isInstance(exception))        throw excType.cast(exception);    return this;  }  public <E extends Throwable, F extends Throwable> Exceptional<T> propagate(      Class<E> excType, Function<? super E, ? extends F> translator)  throws F  {    if (excType.isInstance(exception))      throw translator.apply(excType.cast(exception));    return this;  }  public <E extends Throwable, F extends Throwable> Exceptional<T> propagate(      Iterable<Class<E>> excTypes, Function<? super E, ? extends F> translator)  throws F  {    for (Class<? extends E> excType : excTypes)      if (excType.isInstance(exception))        throw translator.apply(excType.cast(exception));    return this;  }  public <E extends Throwable> Exceptional<T> handle(Class<E> excType, Consumer<? super E> action) {    if (excType.isInstance(exception)) {      action.accept(excType.cast(exception));      return empty();    }    return this;  }  public <E extends Throwable> Exceptional<T> handle(Iterable<Class<E>> excTypes, Consumer<? super E> action) {    for (Class<? extends E> excType : excTypes)      if (excType.isInstance(exception)) {        action.accept(excType.cast(exception));        return empty();      }    return this;  }  public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {    if (value != null) return value;    if (exception != null) sneakyThrow(exception);    throw exceptionSupplier.get();  }  public boolean isPresent() {    return value != null;  }  public void ifPresent(Consumer<? super T> consumer) {    if (value != null)      consumer.accept(value);    if (exception != null) sneakyThrow(exception);  }  public boolean isException() {    return exception != null;  }  @Override  public boolean equals(Object obj) {    if (this == obj) return true;    return obj instanceof Exceptional && Objects.equals(value, ((Exceptional)obj).value);  }  @Override  public int hashCode() {    return Objects.hashCode(value);  }  @SuppressWarnings("unchecked")  private static <T extends Throwable> void sneakyThrow(Throwable t) throws T {    throw (T) t;  }}

@FunctionalInterfacepublic interface TrySupplier<T> {  T tryGet() throws Throwable;}

@FunctionalInterfacepublic interface TryRunnable {  void run() throws Throwable;}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5178025.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-18
下一篇 2022-11-18

发表评论

登录后才能评论

评论列表(0条)

保存