Optional
Optional是JDK8新引进的一个应对null的流式api
Optional和stream流同时加入,但是现在stream流大火,而Optional鲜有使用,为什么呢?
一开始我是不怎么喜欢用Optional的,当时我认为Optional方法长,不美观,感觉不如==null
但是公司项目在使用可能空值是强制使用Optional(可能leader是rust粉丝?),接手项目后我发现Optional真香 吗?
函数返回值
我们组的规范是:
- 函数返回值可能是null的,强制用Optional包裹
- 对于必须返回非空的返回值,如果
result==null
,抛出对应异常
Optional大量使用的好处就是:强制判空,提醒了我们哪里需要判空,减少了冗余判空和漏判的发生。
举个常见的例子
应用中我们经常要获取用户Id。项目封装两个方法
public static Optional<Long> getUserIdOpt(){
return Optional.ofNullable(id);
}
public static long getUserId(){
return getUserIdOpt().orElseThrow(UserNotLoginException::new);
}
这两个方法对比就很明显,当用户未登录时id=null,用getUserIdOpt获取的值可能为空就要用Optional封装
外部数据
对于从外部获取(sql/nosql/rpc)的返回值,使用时需要用判空或用Optional包裹,下面给出例子
public static void main(String[] args) {
//get user
User user = rpcGetUser().orElseThrow(new RpcException());
//get email
String email = Optional.ofNullable(user.getEmail()).orElse("");
}
public static Optional<User> rpcGetUser(){
//...
return Optional.ofNullable(user);
}
但是真的解决问题了吗
Optional对于判空一个多变量的对象似乎很无力。
一个对象里面如果有很多字段,并且这些字段都有可能为空
这时我们要使用这些字段,就都要用Optional包装,这其实已经和==null
没什么区别了
除非我们用Optional当参数?但是这是不可行的
- Optional当参数,本身需要判空
- Optional序列化问题
public static void func(Optional<User> userOpt){
if(userOpt != null && userOpt.isPresent()){
//not null
}
}
所以Optional不是万能的,它可以帮助我们在方法的出参进行包装校验, 但是在类对象的属性判空,方法传参,类属性使用并不理想。我想这可能就是Optional不火的原因之一吧