java.lang.NullPointException这个异常,写过几年Java的没人没遇到过这个, 为了避免抛出这个异常,我们经常会写出这样的代码:
User pet = userDao.findById(1);
if (null != user) {
return user.getName();
}
扎心的是,我们经常会忘记写这个判断, 然后NullPointException就来了.
在Java的世界里,为了避免这个问题, 有一个模式叫做Null Object,主要做法就是为某个可能为null的对象单独创建一个特殊的对象, 如Collections.emptyList(), Collections.emptyMap();等, 这个做法非常繁琐,如果想大规模使用的话,我们几乎要为每个类编写Null Object.
当返回可空对象时,会遇到的另外一个问题是,IDE无法帮助我们提前提示可能出错的情况,以前的做法是,在可能返回空对象的方法上加入@Nullable注解来让IDE识别到这种情况.
还好, 在Java8中,为我们提供了另外一种选择Optional(Guava中存在很久的概念).Optional是对可以为空的对象的一种封装.
那自从有了Optional后情况会变得怎么样呢?
如何创建一个Optional对象
// 明确不为空的时候使用, 如果object为空,会抛出 NullPointExceptioin
Optional.of(object);
// 可能为空的时候使用
Optional.ofNullable(object);
// 肯定为空的时候使用
Optional.empty();
当我我们拿到一个Optional对象的时候,能做些什么呢
// 第一种用法, 普通非空检查判断
public Optional getUserNameById(int id) {
Optional userOptioanl = userDao.findById(1);
if (userOptional.isPersent()) {
final User user = userOptional.get();
return Optional.ofNullable(user.getName());
}
return Optional.empty();
}
// 第二种, 如果为空,抛出异常
public Optional getUserNameById(int id) throws UserNotFoundException {
Optional userOptioanl = userDao.findById(1);
final String name = userOptional.orElseThrow(UserNotFoundException::new).getName();
return Optioanl.ofNullable(name);
}
// 第三种, 当对象为空时,给一个默认值
public void userDoSomething(int userId) {
final User manager = getManager();
Optional userOptioanl = userDao.findById(1);
// 如果找不到这个人, 事情交给经理去做
userOptional.orElse(manager).doSomething();
}
// 第四种, 使用lambda
public void userDoSomething(int userId) {
final User manager = getManager();
Optional userOptioanl = userDao.findById(1);
userOptioanl.ifPresent(user -> {
user.doSomething();
});
}
其它的filter, map, flatMap等方法和Java8 Streams API类似
如果想期待代码量变少,可能要失望了, 当从代码量来说,甚至比原来的代码都多,但好处就是,绝对不会忘记做非空判断, 除非每次都傻傻的直接调用get