Java中避免写嵌套if样式的代码详解
前言
Optional的代码相对更加简洁,当代码量较大时,我们很容易忘记进行null判定,但是使用Optional类则会避免这类问题。
下面这是一个嵌套的if判断,业务逻辑是从httpRequst中获取X-Auth-Token的值。逻辑是如果header中有值则从header中取值否则从cookie中取值,取到值后调用一个http远程接口获取用户信息,获取不到则报“获取用户信息失败”,如果token都不存在则直接返回httpRespons为401-NoAuth
这下面是之前同事写的代码
if嵌套代码
if(methodNeedAuth){ //***身份验证 Stringtoken=request.getHeader("X-Auth-Token"); if(StringUtils.isEmpty(token)){//如果header中没有X-Auth-Token则从cookie中取 Cookie[]cookies=request.getCookies(); if(cookies==null||cookies.length==0){//cookie都为null returnreturnNoAuthResult(response); }//这个地方判空,否则下面的Arrays.stream回报空指针异常 token=Arrays.stream(cookies).filter(cookie-> "X-Auth-Token".equals(cookie.getName()) ).collect(Collectors.toList()).get(0).getValue(); if(token==null){//cookie有值但是cookie中没有X-Auth-Token returnreturnNoAuthResult(response); } } if(!StringTool.isNullOrEmpty(token)){ userInfo=userService.getUserInfoByToken(token); } if(userInfo==null||StringTool.isNullOrEmpty(userInfo.getUser_id())){ returnreturnNoAuthResult(response); } }
Optional规避if嵌套
if(methodNeedAuth){ //***身份验证 Stringtoken=Optional.ofNullable(request.getHeader("X-Auth-Token")).orElseGet(()-> getTokenFromCookie(request)//提取出一个方法 ); userInfo=Optional.ofNullable(token).map(Try.of(t-> userService.getUserInfoByToken(t)) ).orElse(null); if(userInfo==null||StringTool.isNullOrEmpty(userInfo.getUser_id())){ response.sendError(401,"noauth"); returnfalse; } } /** *从cookie中获取token */ privateStringgetTokenFromCookie(HttpServletRequestrequest){ Cookie[]cookies=Optional.ofNullable(request.getCookies()).orElse(newCookie[0]);//Optional强制赋默认值,cookies一定不为null Stringcookie=Arrays.stream(cookies).filter(item-> "X-Auth-Token".equals(item.getName()) ).findFirst().map(Cookie::getValue).orElse(null); returncookie; }
小结
Java8Optional的常规用法
Java8的Optional可以规避所有的空指针异常问题么?答案当然是否定的,Optional
Optional的三种构造方式:Optional.of(obj),Optional.ofNullable(obj)和明确的Optional.empty()
- Optional.of(obj):它要求传入的obj不能是null值的,否则还没开始进入角色就倒在了NullPointerException异常上了.
- Optional.ofNullable(obj):它以一种智能的,宽容的方式来构造一个Optional实例.来者不拒,传null进到就得到Optional.empty(),非null就调用Optional.of(obj).
那是不是我们只要用Optional.ofNullable(obj)一劳永逸,以不变应二变的方式来构造Optional实例就行了呢?那也未必,否则Optional.of(obj)何必如此暴露呢,私有则可?
我本人的观点是:
- 当我们非常非常的明确将要传给Optional.of(obj)的obj参数不可能为null时,比如它是一个刚new出来的对象(Optional.of(newUser(…))),或者是一个非null常量时;
- 当想为obj断言不为null时,即我们想在万一obj为null立即报告NullPointException异常,立即修改,而不是隐藏空指针异常时,我们就应该果断的用Optional.of(obj)来构造Optional实例,而不让任何不可预计的null值有可乘之机隐身于Optional中.
Java8Optional需要小心的地方
- Reportscallstojava.util.Optional.get()withoutfirstcheckingwithaisPresent()callifavalueisavailable.IftheOptionaldoesnotcontainavalue,get()willthrowanexception.(调用Optional.get()前不事先用isPresent()检查值是否可用.假如Optional不包含一个值,get()将会抛出一个异常)
- Reportsanyusesofjava.util.Optional,java.util.OptionalDouble,java.util.OptionalInt,java.util.OptionalLongorcom.google.common.base.Optionalasthetypeforafieldoraparameter.Optionalwasdesignedtoprovidealimitedmechanismforlibrarymethodreturntypeswherethereneededtobeaclearwaytorepresent“noresult”.Usingafieldwithtypejava.util.OptionalisalsoproblematiciftheclassneedstobeSerializable,whichjava.util.Optionalisnot.(使用任何像Optional的类型作为字段或方法参数都是不可取的.Optional只设计为类库方法的,可明确表示可能无值情况下的返回类型.Optional类型不可被序列化,用作字段类型会出问题的)
一句话小结:使用Optional时尽量不直接调用Optional.get()方法,Optional.isPresent()更应该被视为一个私有方法,应依赖于其他像Optional.orElse(),Optional.orElseGet(),Optional.map()等这样的方法.
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。