侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

单纯的使用Optional并不能很好的解决业务中的NPE问题

2022-06-27 星期一 / 0 评论 / 0 点赞 / 86 阅读 / 5652 字

工作中经常会遇到NPE(NullPointException)问题怎么处理,得到最多的回答就是Optional来处理,但是单纯的使用Optional并不能很好的解决业务中的NP问题。所以整理出日常工作

工作中经常会遇到NPE(NullPointException)问题怎么处理,得到最多的回答就是Optional来处理,但是单纯的使用Optional并不能很好的解决业务中的NP问题。所以整理出日常工作中处理NPE问题的思路,供参考。

先看一下思路:

01 避免的操作

01.01 避免入参使用 Optional

日常工作中有是看到如下代码。

public void execute(Optional<String> nameOptional) {   ...}

如果方法的某个参数可能为null,那么可以使用方法重载,而不是传入一个null。因为代码的实现上揭示业务意图要要好于只表示业务意图,因为在业务上null没有业务意义,如果出现null,而又需要处理相关逻辑,那么可以使用方法重载。

另外,方法调用者将很清晰起作用的参数,也不需要为了调用某个方法而构造Optional。

public void execute() {     execute(null);}public void execute(String name) {    ...}

上面的代码避免了对外方法的意图模糊,同时也避免了部分的重复代码。

01.02 避免多行 if() 语句

“使用了Optional,也没有感觉逻辑变变简单啊,每次都得get()方法”,这是工作中听到的刚刚接触Optional的开发人员的表述。

问题在哪里呢?如果我们有一把把核桃夹子,但是每次用这把核桃夹子做的事情都是砸核桃,那么就发现和用锤子砸也没有什么区别,结果都是碎了一地。

我们都说代码时重构出来的,而不是设计出来的。所以实现的时候如果对Optional不熟悉可以使用if来判断,重构的时候可以试着寻找一些能够有更好的解决办法。因为switch语句本来就是坏味道,寻找的方向可以先看看Optional除了提供了get方法,还提供了哪些方法,它们都是做什么用途的。

02 如何做

02.01 使用返回值中用Optional显式处理

如果实际实现中需要我们将null值返回,我们可以return一个Optioanl对象回去,这样该方法的调用者就必须就知道返回中有可能为null,并对其进行特定的处理。

public Optional<Data> execute() {    ...	return Optional.empty();}

02.02 适当的时候使用Exception

并不是找不到结果我们就只能选择返回Optiona.empty(),除非逻辑需要继续执行而不期望中断,否则我们可以直接选择抛出异常。

例如,根据username、password寻找用户的方法,如果找不到用户,可以直接抛出InvalidUsernameOrInvalidPasswordException。

public User login(String name, String password) {	...		throw new InvalidUsernameOrInvalidPasswordException();}

那么,外层要么进行异常处理,要么Project进行全局异常捕获,统一进行处理。

02.03 使用Optional Lambda

在01.02中提到了因为对Optional提供的方法不熟悉,而感觉和null值判断没有多大区别。那么推荐根据业务场景来选择Optioanl Lambda的写法。

String name = computer.flatMap(Computer::getSoundcard)	.flatMap(Soundcard::getUSB)	.map(USB::getVersion) 	.orElse("UNKNOWN");

上面写法要比下面的写法清晰很多。当然这需要保持好奇心,多学习一点工具类提供的方法,同时别总是制作简单的搬砖工作。

String version = "UNKNOWN";if (computer != null) {	Soundcard soundcard = computer.getSoundcard();	if (soundcard != null) {		USB usb = soundcard.getUSB();		if (usb != null) {			 version = usb.getVersion(); 		} 	}}

参考

02.03最终的代码来源

.
.

广告 广告

评论区