java 以._java – 以功能方式处理异常的更好方法

下面提供了Exceptional类的完整代码。它有一个相当大的API,它是可选API的纯扩展,所以它可以是任何现有代码中的一个替代,除了它不是最后的可选类的子类型。类可以看作与

Try monad具有相同的关系,可选是与Maybe monad:它从它吸取灵感,但适应Java成语(如实际抛出异常,甚至从非终端操作) 。

这些是课程遵循的一些关键指导方针:

>相对于monadic方法,不忽略Java的异常机制;

>而是它减轻了异常和高阶函数之间的阻抗失配;

>异常处理不是静态类型安全的(由于偷偷摸摸的抛出),但在运行时总是安全的(除非明确请求,否则不会收到异常)。

类试图覆盖所有典型的处理异常的方法:

>恢复一些提供替代值的处理代码;

> flatRecover,类似于flatMap,允许返回一个新的异常实例,该实例将被展开并且适当地更新当前实例的状态;

>传播异常,将其从Exceptional表达式中抛出并使propagate调用声明此异常类型;

>将其传播到另一个异常(翻译);

>处理它,导致一个空异常;

>作为一种特殊的处理方式,用一个空的处理程序块来吞下它。

传播方法允许选择性地挑选哪些被检查的异常他想从他的代码暴露。在终端操作被调用时保持未处理的异常(例如get)将被狡猾地抛出而没有声明。这通常被认为是一种高级和危险的方法,但是经常被采用作为一种方式,以在某种程度上减轻检查异常与不声明它们的lambda形状的组合的麻烦。异常类希望提供一个更清洁和更有选择性的替代鬼祟。

/*

* Copyright (c) 2015, Marko Topolnik. All Rights Reserved.

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

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

{

private final T value;

private final Throwable exception;

private Exceptional(T value, Throwable exc) {

this.value = value;

this.exception = exc;

}

public static Exceptional empty() {

return new Exceptional<>(null, null);

}

public static Exceptional ofNullable(T value) {

return value != null ? of(value) : empty();

}

public static Exceptional of(T value) {

return new Exceptional<>(Objects.requireNonNull(value), null);

}

public static Exceptional ofNullableException(Throwable exception) {

return exception != null? new Exceptional<>(null, exception) : empty();

}

public static Exceptional ofException(Throwable exception) {

return new Exceptional<>(null, Objects.requireNonNull(exception));

}

public static Exceptional from(TrySupplier supplier) {

try {

return ofNullable(supplier.tryGet());

} catch (Throwable t) {

return new Exceptional<>(null, t);

}

}

public static Exceptional fromVoid(TryRunnable task) {

try {

task.run();

return new Exceptional<>(null, null);

} catch (Throwable t) {

return new Exceptional<>(null, t);

}

}

public static 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 Exceptional 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 Exceptional flatMap(Function super T, Exceptional> mapper) {

Objects.requireNonNull(mapper);

return value != null ? Objects.requireNonNull(mapper.apply(value)) : empty();

}

public Exceptional 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 Exceptional 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 Exceptional recover(

Iterable> 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 Exceptional flatRecover(

Class extends X> excType, Function super X, Exceptional> mapper)

{

Objects.requireNonNull(mapper);

return excType.isInstance(exception) ? Objects.requireNonNull(mapper.apply(excType.cast(exception))) : this;

}

public Exceptional flatRecover(

Iterable> excTypes, Function super X, Exceptional> 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 Exceptional propagate(Class excType) throws E {

if (excType.isInstance(exception))

throw excType.cast(exception);

return this;

}

public Exceptional propagate(Iterable> excTypes) throws E {

for (Class extends E> excType : excTypes)

if (excType.isInstance(exception))

throw excType.cast(exception);

return this;

}

public Exceptional propagate(

Class excType, Function super E, ? extends F> translator)

throws F

{

if (excType.isInstance(exception))

throw translator.apply(excType.cast(exception));

return this;

}

public Exceptional propagate(

Iterable> 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 Exceptional handle(Class excType, Consumer super E> action) {

if (excType.isInstance(exception)) {

action.accept(excType.cast(exception));

return empty();

}

return this;

}

public Exceptional handle(Iterable> 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 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 void sneakyThrow(Throwable t) throws T {

throw (T) t;

}

}

@FunctionalInterface

public interface TrySupplier {

T tryGet() throws Throwable;

}

@FunctionalInterface

public interface TryRunnable {

void run() throws Throwable;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值