java中process方法用处_Java中错误传播以及处理方法

每个应用程序都生活在现实世界中,而现实世界并不完美。因此,即使是理想的,无错误的应用程序也注定会不时地处理错误。

7e9cd151c7cedf6ea35c9de121fd333f.png

自从第一个计算机程序诞生以来,问题就一直存在,软件工程师发明了许多错误处理方法!

Java传统上使用以下方法向调用者发出信号,指出存在错误:

· 返回一个特殊值(通常,为此目的使用“ null”值)

· 引发异常

这两种方法都有明显的缺点。

返回一个特殊值将丢弃有关错误实际原因的信息,并通过附加检查使代码膨胀。

与正常的执行流程相比,异常的代价非常高,并且使流程难以遵循且难以验证其正确性。一些库和框架倾向于滥用异常,以使其成为正常执行流程的一部分,这是很疯狂的。

因此,有没有其他方法可以通知呼叫者有关错误而又没有上述缺点?是! 函数式编程提供了一种。

请注意,在下文中,我将尽量避免使用FP专用术语。这不会降低方法的功能性,但是可以为那些还不习惯FP lang语的人简化概念。

该Either集装箱

这个想法是使用容器作为返回值,而不是普通值。容器很特殊:虽然被声明为两种类型,但实际上在第一或第二种类型中,每次仅保存一个值。

的Either是通用的容器,不依赖于误差传播/处理。当将其用于错误传播时,按照约定,第一种(或“左”)类型用于表示错误类型,而第二种(或“右”)类型表示返回值类型。

在代码中,这看起来像:

Either parseUUID(final String input) {

2

...

3

// failure

4

return Either.left(ErrorDetails.of("Unable to parse UUID"));

5

...

6

// success

7

return Either.right(uuid);

8

}

实际上,与通常的“做某事并成功返回结果,如果有错误则抛出异常”并没有什么不同。

更深入的外观具有很多优点:

· 不再需要返回一些“特殊”值。

· 有关该错误的信息仍然可用。

· 执行流程没有中断。

上面的代码演示了“生产”方面。现在,让我们看一下“消费”方面的样子:

...// Service interface

2

Either getUserById(final UUID uuid);

3

4

...//Actual use

5

return parseUUID(parameter).flatMapRight(service::getUserById);

此可疑简单代码包含处理错误所需的一切:

· 如果任何处理步骤返回错误,它将返回正确的错误结果。

· 一旦发生错误,它将立即停止处理。

· 它不会中断执行流程, return语句将始终执行,并且始终将值返回给调用方。

· 它强制执行“处理错误或传播错误”策略,从而产生健壮的代码。

· 这种方法的一致应用会产生清晰易读的代码。

专门研究狭窄的用例

可能会注意到,plain Either用于错误处理时非常冗长。

首先,它要求明确引用错误类型。尽管通常错误的基本类型并不多。例如,Java使用单一Throwable类型作为所有错误和异常的基类。

冗长和不便的第二个来源(出于此特定目的)是Either一般意义上的意义,即它可以用于任何类型,并且其API在双方方面都是对称的。当Either用于错误处理时,这要求某些约定的一致应用,例如上面提到的约定。

因此,对于狭义的错误处理,Either可以将其专门化为Result类型,该类型假定单个通用的错误基本类型,并已针对错误处理调整了API。这使代码不再那么冗长,也更容易发生意外错误。

使用Result,上面的代码可以重写为以下代码:

...

2

3

Result parseUUID(final String input) {

4

...

5

return Result.failure(ErrorDetails.of("Unable to parse UUID"));

6

...

7

return Result.success(uuid);

8

}

9

10

...// Service interface

11

Result getUserById(final UUID uuid);

12

13

...

14

return parseUUID(parameter).flatMap(service::getUserById);

现在,代码不再那么冗长,而上面提到的所有属性仍然存在。

修改现有代码以供使用 Result

使用的Result是在自己的代码方便,但我们生活在Java库和框架,不使用它的世界。他们抛出异常并返回空值。因此,我们需要一种方便的方法来与现有代码进行交互。

为此,Reactive Toolbox Core中的 Result实现提供了一组帮助程序方法,该方法允许将传统方法包装到返回Result的方法中。

下面的示例显示如何使用这些辅助方法:

1

interface PageFormattingService {

2

Result format(final URI location);

3

}

4

5

private PageFormattingService service;

6

7

private Result formatPage(final String requestUri) {

8

return lift(URI::create)

9

.apply(requestUri)

10

.flatMap(service::format);

11

}

最后,开发这么多年我也总结了一套学习Java的资料与面试题,如果你在技术上面想提升自己的话,可以关注我,私信发送领取资料或者在评论区留下自己的联系方式,有时间记得帮我点下转发让跟多的人看到哦。

7e8c1c5aa8637c3c3b195ed843ea1280.png
1ede2817551b74c8f5f9697890ade603.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值