else子句的陷阱

写完上一篇关于else-if子句的陷阱后,想起来以前还遇到过类似的关于else子句以及switch表达式中default条件的陷阱,本文就记录这个问题,并给出相关解决方案/建议。

问题描述

相信大家在工作中都见到过类似的代码:

if (mediaInfo.getType() == MP3) {
    //...处理mp3的情况
} else { //假设此时的type只有mp3和mp4两种值时
    //...处理mp4的情况
}

一开始我们的type只有MP3MP4两种,有时候为了方便,就用if子句处理MP3而用else子句来处理MP4的情况,这是一个比较糟糕的实践。这样的写法可能会导致意料之外的bug,因为这里的else子句有以下两个性质:

  1. else的条件是隐式的,需要根据上下文推导,而不是直接观测;
  2. else的条件是变化的,当新增else-if子句的时候,else的条件也会发生变化。

性质一使得else的条件不是那么直观,这又会放大性质二中的问题。也就是说,当else的条件发生变化时,它不是可以直接观测到的,容易被忽略,那么就可能因为修改代码时没有注意到条件的改变而导致程序逻辑错误。

比如,上面那段程序,今天增加了MKV的视频类型,在忘记添加相应的else-if判断子句的时候就会导致程序正常编译且可以运行,但是可能导致程序的逻辑错误:把MKV当作MP4处理。有时候,负责添加MediaInfotype值类型的开发者并不负责这个数据类型的使用,这就导致了问题的发生。

导致上面问题的另一个原因是这段程序中else子句的条件并不是单一条件,它包含了:

  1. type为MP4的情况;
  2. typeMP3MP4以外的非法值的情况。

解决方法或建议

上面程序改成下面这样会是比较好的实践:

if (mediaInfo.getType() == MP3) {
    //...处理mp3的情况
} else if (mediaInfo.getType() == MP4){
    //...处理mp4的情况
} else { //例外情况
    //处理非法值的情况,记录日志或抛出异常
}

这样在新增类型值的时候如果忘记添加子句,那么在程序运行的时候就可以根据日志或崩溃记录及时发现问题根源,且程序的表达更加明确。

最后,总结得出以下建议:

  1. else子句不要包含隐式复合条件,很可能其中就有变化的条件,而这个变化可能无法直接观测到;
  2. 条件分支中正常情况通过ifelse-if来处理,而else只处理例外情况;
  3. 值的枚举处理可以通过swtich表达式或模式模式匹配来完成,if-else仅用于简单条件(比如,isEmpty、isNull),因为这种情况下条件的分支数是固定的(只有是否两个),而else的条件也是固定的(如果if条件中是isXXX,那么else子句就是isNotXXX
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值