紧接着运行maven,对项目进行编译 。
mvn clean compile findbugs:findbugs
文章插图
可以看到,findbugs 发现可能会在运行期间出现 NPE 后,中断了项目构建过程 。
我们再打开 findbugs 的界面看看具体的报错位置:
文章插图
你瞧,findbugs 准确的找到了可能出现 NPE 的根源 。
通过以上这些手段,我们尽可能的将 NPE 提前到编译期发现 。
但是啊但是,对一个规模庞大且复杂的项目来说,光使用静态代码检查还是不够的 。因为类似 findbugs 这种的静态代码检查工具 , 不可能对每个 NPE 的检查点都检查到位 。并且,探测的问题有时候因为业务原因,也会放松检查要求 。
别慌 , 我们可以让静态代码检查再加上一些别的方法,来联手堵住 NPE 问题,这就是我们下面要说的 Optional 。
4. 用 Optional 去除二义性
由于铺天盖地的 null 检查,使得 Java 程序员叫苦不堪 。于是官方自 Java8 起 , 参考了 google 的 guava,引入了 Optional 类型用来避免每次繁琐丑陋的 null 检查 。
Optional 本质上就是一个容器,这个容器持有了一个变量类型为 T 的值 。所以,Optional 这个容器中的值只会有两种情况,要么为类型 T 的变量值,要么为null 。
对于可能出现的为 null 的情况,Optional 本身从创建、检查,到抽取、使用 , 都提供了对应的方法供使用者调用 。并采用了意义很明确的方法去排除了null的二义性 。
我们看示例代码:
class Player{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}public class Optional4NPE { public static void main(String[] args) { Optional<Player> optiOnalPlayer= Optional.ofNullable(null); optionalPlayer.ifPresent(u -> System.out.println(u.getName())); }}
以上代码我们使用了一个 Optional 中的 ofNullable,去创建了一个包含了类型为 Player、值为 null 的 Optional 容器 。运行结果:
'Process finished with exit code 0'
运行后,代码没有任何输出,也没有出现 NPE 异常 。没有输出的原因是我们传入了一个 null 值 , 这个 null 表示值不存在 。此时,我们调用 Optional 的 ifPresent 方法做了判断,只有存在值时,才会执行打印输出 。
接下来,我们把 null 替换成有意义的值看看 。
import java.util.Optional;class Player{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}public class Optional4NPE { public static void main(String[] args) { Player player = new Player(); player.setId(1); player.setName("demoUser"); Optional<Player> optiOnalPlayer= Optional.ofNullable(player); optionalPlayer.ifPresent(u -> System.out.println(u.getName())); }}
输出结果:demoUserProcess finished with exit code
可以看到,当传入一个我们创建的 player 时 , 执行了打印输出方法 。上面我们已经发现,通过 Optional 的 ifPresent 方法,我们明确了 null 的含义,明确认定只要值为 null , 就表示不存在 。那如果一个变量存在,但是没有值或者没有有意义的值呢?
我们把代码改改:
import java.util.Optional;class Player{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}public class Optional4NPE { public static void main(String[] args) { Player player = null; Player defaultPlayer = new Player(); defaultPlayer.setId(1); defaultPlayer.setName("————undefinedNAME-----"); Player player1 = Optional.ofNullable(player).orElse(defaultPlayer); System.out.println(player1.getName()); }}
运行结果如下:————undefinedNAME-----Process finished with exit code 0
这里可以看到,我们使用 orElse 方法,当一个变量值为 null 时 , 返回一个默认值 。通过返回默认值 , 我们明确了 null 的另外一个含义,对象存在,但是可能没有实际意义 。Optional 的出现,大大改善了我们的 Java 代码质量,减少了 NPE 的可能性,并使得代码的可读性大大增强 。
通过使用 Optional,开发人员还能非常自然轻松的使用 Null Object Pattern 模式去处理 Null 问题 。Optional 是非常值得在项目中大范围使用的 。
推荐阅读
- 在重庆游玩,特色火锅是一定要尝一尝的,你能吃多辣呢?
- 《王牌对王牌》二期封神,离不开三位功臣,沈腾已拿到“烦人卡”
- 幽默笑话:我不会做家务,乱花钱还很任性,你能接受我吗?
- 到底什么精华才算抗老精华呢?看完这5款大牌精华或许你能明白点
- 《花少5》好失望,大明星又懒又迷之自信,有三位已拿烦人卡
- 7个皮肤敏感期间的护理误区,你能避开几个?
- 系统提示null什么意思
- 唐嫣秋冬时尚大片:羊毛卷发你能认出来吗?
- 减肥的7个小知识,搞懂就能暴瘦20斤,希望你能用上
- MySQL 的 NULL 值是怎么存放的?