一. 介绍
io.vavr.control.Try 是 Vavr 库的一个类,用于处理可能抛出异常的方法调用;它提供了一种优雅的方式来处理成功和失败的情况,而无需显示地使用 try-catch 块;
简而言之,它可以优雅的实现 try-catch;
下面,我们学习一下它的简单基本使用;
二. 简单使用
简单使用如下:
public static void test01() {
// 通过 Try.of(CheckedFunction0 supplier) 来创建一个 Try 对象
Try<Integer> result = Try.of(() -> 1 / 0);
// 执行结果是否成功
System.out.println(result.isSuccess());
System.out.println(result.isFailure());
// getOrElse(T other)
Integer orElse = result.getOrElse(-1);
System.out.println(orElse);
// finally
Try<Integer> result1 = Try.of(() -> 1 / 0)
.andFinallyTry(() -> System.out.println("资源释放"));
// getOrElseThrow() 抛出其他异常
result.getOrElseThrow(() -> new ArithmeticException("除数为0"));
}
打印如下:
false
true
-1
资源释放
Exception in thread "main" java.lang.ArithmeticException: 除数为0
at com.zengqiang.testTry.Test01.lambda$test01$1(Test01.java:26)
at io.vavr.Value.getOrElseThrow(Value.java:395)
at com.zengqiang.testTry.Test01.test01(Test01.java:26)
at com.zengqiang.testTry.Test01.main(Test01.java:8)
三. 类结构
Try 是一个接口,具体实现类是 Success 和 Failure;
- Try.of() 中如果执行成功,返回结果是 Success,Success 中会保存方法返回值;
- Try.of() 中如果执行失败,即出现了异常,返回结果是 Failure,Failure 中会保存异常对象;
了解了 Try 的类结构,我们知道,Try 中定义了一些接口,Success、Failure 中定义了实际实现;
下面来看下几个方法的源码;
四. 源码
1. Try.of()
Try.of(CheckedFunction0<? extends T> supplier) 是一个静态方法,返回一个 Try 对象;
// --------------------------------- Try ------------------------------------
static <T> Try<T> of(CheckedFunction0<? extends T> supplier) {
try {
// 1. 执行成功的话创建并返回 Success 对象
return new Success<>(supplier.apply());
} catch (Throwable t) {
// 2. 执行失败,抛出异常的话创建并返回 Failure 对象
return new Failure<>(t);
}
}
1.1 Success
Success 的代码非常简短,如下所示;
final class Success<T> implements Try<T>, Serializable {
private static final long serialVersionUID = 1L;
private final T value;
/**
* 构造创建 Success 对象
* this.value = value
*
*/
private Success(T value) {
this.value = value;
}
/**
* get() 返回 value 值
*/
@Override
public T get() {
return value;
}
@Override
public Throwable getCause() {
throw new UnsupportedOperationException("getCause on Success");
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean isFailure() {
return false;
}
@Override
public boolean isSuccess() {
return true;
}
@Override
public String stringPrefix() {
return "Success";
}
@Override
public String toString() {
return stringPrefix() + "(" + value + ")";
}
}
1.2 Failure
Failure 的代码非常简短,如下所示;
final class Failure<T> implements Try<T>, Serializable {
private static final long serialVersionUID = 1L;
private final Throwable cause;
/**
* 构造 Failure 对象
* this.cause = cause
*/
private Failure(Throwable cause) {
Objects.requireNonNull(cause, "cause is null");
if (isFatal(cause)) {
sneakyThrow(cause);
}
this.cause = cause;
}
/**
* get() 抛出异常 cause
*/
@Override
public T get() {
return sneakyThrow(cause);
}
@Override
public Throwable getCause() {
return cause;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public boolean isFailure() {
return true;
}
@Override
public boolean isSuccess() {
return false;
}
@Override
public String stringPrefix() {
return "Failure";
}
@Override
public String toString() {
return stringPrefix() + "(" + cause + ")";
}
}
2. Try.getOrElse()
try.getOrElse() 的逻辑也比较简单易懂;
// --------------------------------- Try ------------------------------------
default T getOrElse(T other) {
// 1. 如果是 Success
// isEmpty() == false,get() 返回 value 值
// 2. 如果是 Failure
// isEmpty() == true, 返回 other 值
return isEmpty() ? other : get();
}
3. Try.andFinallyTry()
try.andFinallyTry() 是类比于 try-catch-finally 中的 finally;
// --------------------------------- Try ------------------------------------
default Try<T> andFinallyTry(CheckedRunnable runnable) {
try {
// 1. 执行 runnable.run(),并返回 this
runnable.run();
return this;
} catch (Throwable t) {
// 2. 如果出现了异常,返回 Failure 对象
return new Failure<>(t);
}
}
4. Try.getOrElseThrow()
try.getOrElseThrow() 逻辑也比较清晰易懂;
default <X extends Throwable> T getOrElseThrow(Supplier<X> supplier) throws X {
// 1. 如果是 Failure,isEmpty() == true,执行并抛出 supplire.get()
// 2. 如果是 Success,isEmpty() == false,执行并返回 get()
if (isEmpty()) {
throw supplier.get();
} else {
return get();
}
}
至此,Try 学习完毕,Try 的其他用法我们遇到的时候再举一反三;