下面显示的是
Exceptional该类的完整代码。它具有相当大的API,是对
OptionalAPI 的纯扩展,因此可以在任何现有代码中直接替换它-
除非它不是最终
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;}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)