城市直播房产教育博客汽车
快传网
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

求求你,不要再使用!null判空了

4月8日 听雨眠投稿
  对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。
  那么,有什么办法可以避免在代码中写大量的判空语句呢?
  有人说可以使用JDK8提供的Optional来避免判空,但是用起来还是有些麻烦。
  作者在日常工作中,封装了一个工具,可以可以链式调用对象成员而无需判空,相比原有的ifnull逻辑和JDK8提供的Optional更加优雅易用,在工程实践中大大提高了编码效率,也让代码更加的精准和优雅。
  不优雅的判空调用
  我想从事Java开发的小伙伴肯定有遇到过下面这种让人难受的判空逻辑:现在有一个User类,School是它的成员变量authorAxinsince20200920summary一个User类定义(Ps:Data是lombok组件提供的注解,简化了getset等等的约定代码)DatapublicclassUser{privateSprivateSprivateSDatapublicstaticclassSchool{privateStringscNprivateS}}复制代码
  现在想要获得School的成员变量adress,一般的处理方式:publicstaticvoidmain(String〔〕args){UseraxinnewUser();User。SchoolschoolnewUser。School();axin。setName(hello);if(Objects。nonNull(axin)Objects。nonNull(axin。getSchool())){User。SchooluserScaxin。getSchool();System。out。println(userSc。getAdress());}}复制代码
  获取adress时要对School进行判空,虽然有些麻烦,到也能用,通过JDK8提供的Optional工具也是可以,但还是有些麻烦。
  而下文的OptionalBean提供一种可以链式不断地调用成员变量而无需判空的方法,直接链式调用到你想要获取的目标变量,而无需担心空指针的问题。
  链式调用成员变量
  如果用了本文设计的工具OptionalBean,那么上述的调用可以简化成这样:publicstaticvoidmain(String〔〕args){UseraxinnewUser();User。SchoolschoolnewUser。School();axin。setName(hello);1。基本调用Stringvalue1OptionalBean。ofNullable(axin)。getBean(User::getSchool)。getBean(User。School::getAdress)。get();System。out。println(value1);}复制代码
  执行结果:
  其中User的school变量为空,可以看到代码并没有空指针,而是返回了null。这个工具怎么实现的呢?
  OptionalBean工具authorAxinsince20200910summary链式调用bean中value的方法publicfinalclassOptionalBeanT{privatestaticfinalOptionalB?EMPTYnewOptionalBean();privatefinalTprivateOptionalBean(){this。}空值会抛出空指针paramvalueprivateOptionalBean(Tvalue){this。valueObjects。requireNonNull(value);}包装一个不能为空的beanparamvalueparamTreturnpublicstaticTOptionalBeanTof(Tvalue){returnnewOptionalBean(value);}包装一个可能为空的beanparamvalueparamTreturnpublicstaticTOptionalBeanTofNullable(Tvalue){returnvaluenull?empty():of(value);}取出具体的值paramfnparamRreturnpublicTget(){returnObjects。isNull(value)?null:}取出一个可能为空的对象paramfnparamRreturnpublicROptionalBeanRgetBean(F?superT,?extendsRfn){returnObjects。isNull(value)?OptionalBean。empty():OptionalBean。ofNullable(fn。apply(value));}如果目标值为空获取一个默认值paramotherreturnpublicTorElse(Tother){returnvalue!null?value:}如果目标值为空通过lambda表达式获取一个值paramotherreturnpublicTorElseGet(S?extendsTother){returnvalue!null?value:other。get();}如果目标值为空抛出一个异常paramexceptionSupplierparamXreturnthrowsXpublicXextendsThrowableTorElseThrow(S?extendsXexceptionSupplier)throwsX{if(value!null){}else{throwexceptionSupplier。get();}}publicbooleanisPresent(){returnvalue!}publicvoidifPresent(C?superTconsumer){if(value!null)consumer。accept(value);}OverridepublicinthashCode(){returnObjects。hashCode(value);}空值常量paramTreturnpublicstaticTOptionalBeanTempty(){SuppressWarnings(unchecked)OptionalBeanTnone(OptionalBeanT)EMPTY;}}复制代码
  工具设计主要参考了Optional的实现,再加上对链式调用的扩展就是上述的OptionalBean。
  getBean其实是当变量为空时返回了一个包装空值的OptionalBean对象,同时泛型的使用让工具更加易用。
  使用手册
  可以看到代码中也提供了和Optional一样的扩展方法,如ifPresent()、orElse()等等:publicstaticvoidmain(String〔〕args){UseraxinnewUser();User。SchoolschoolnewUser。School();axin。setName(hello);1。基本调用Stringvalue1OptionalBean。ofNullable(axin)。getBean(User::getSchool)。getBean(User。School::getAdress)。get();System。out。println(value1);2。扩展的isPresent方法用法与Optional一样booleanpresentOptionalBean。ofNullable(axin)。getBean(User::getSchool)。getBean(User。School::getAdress)。isPresent();System。out。println(present);3。扩展的ifPresent方法OptionalBean。ofNullable(axin)。getBean(User::getSchool)。getBean(User。School::getAdress)。ifPresent(adressSystem。out。println(String。format(地址存在:s,adress)));4。扩展的orElseStringvalue2OptionalBean。ofNullable(axin)。getBean(User::getSchool)。getBean(User。School::getAdress)。orElse(家里蹲);System。out。println(value2);5。扩展的orElseThrowtry{Stringvalue3OptionalBean。ofNullable(axin)。getBean(User::getSchool)。getBean(User。School::getAdress)。orElseThrow(()newRuntimeException(空指针了));}catch(Exceptione){System。out。println(e。getMessage());}}复制代码
  run一下:
  总结
  设计了一种可以链式调用对象成员而无需判空的工具让代码更加的精准和优雅,如果本文设计的工具满足了刚好解决你的困扰,那就在项目中使用吧!
投诉 评论 转载

竟然有一半的人不知道for与foreach的区别?之前有一个同事突然我问了我一个问题,说在foreach当中能不能删除list里面的元素,我当时大概说了一下是否能删除,以及原因;接下来我们来探讨一下是否能够如此:(1)遍历元素……现在送外卖的配置都这么高了吗?Barq宣称将成为MENA(中东和北非)地区第一家制造电动汽车的制造商并带来了首款专为中东和北非市场(MENA)设计的车型RenaMaxBarq表示这将是一款专为最后一英……一加是否已准备好应对IQOO数字和VIVOx系列?近期,一加新任总裁已经官宣一加未来将主打性能旗舰,以与OPPOfind系列形成定位差异。这也与我之前在看到一片关于一加10pro在未发布时的爆料,在评论中我曾预测一加未来……小米新机型号曝光,小米11让路新机跌至大米价悲惨让路1月13日消息,小米虽然没有realme那么频繁的推出产品,但旗下有多个品牌,产品定位也比较齐全。据悉,一大波新机即将发布。据小米网了解,小米正在开发12款手机,分为两个……冲牙看得清还冲得准,有效地清洁口腔,素诺智能可视冲牙器C3P对于齿缝间顽固菌斑,最简单快速有效的办法就是使用冲牙器。冲牙器像一个小型高压水枪,通过产生极细的高压水线,不仅能把你齿缝间顽固菌斑冲掉,每天坚持使用还可防止牙龈炎和牙结石。市面……iQOONeo3iQOONeo5活力版iQOONeo5对比一、硬件配置3:骁龙865LPDDR4Xufs3。1活力版:骁龙870LPDDR5增强版ufs3。15:骁龙870LPDDR4X增强版ufs3。1独立显示芯片……奇瑞新能源瑞虎e外观设计与现款差异化较大,动力方面搭配了10。25英寸的中控显示屏,并且支持苹果CarPlay和CarLife手机互联功能。这个尺寸也是非常不错的,毕竟它的尺寸已经接近1……深度观察爱玛电动车的危与机爱玛的多重危机,其实每个发展中的企业大都会遇到,尤其是在竞争中处于不进则退的位置上,显得更为凶险,但一念天堂,一念地狱,将其看作冲出困局的突破点,是积极向上的态度。202……微信率先履约,亲测可直接跳转淘宝抖音,安卓用户需更新版本微信外链屏蔽率先解除。近日,工信部召开屏蔽网址链接问题行政指导会,要求各互联网平台限期解除外链屏蔽。9月17日开始,微信率先有所动作,不少用户亲测,在微信中已可点击外链实……黑鲨5系列预热120W秒充航天联名,定档3月30日随着小米与Redmi相继召开发布会后,这两家就再也没有关于新机的确切消息了,但是它们旗下的黑鲨游戏手机却在近日官宣了新机,而此次的主角便是全新的黑鲨5系列,这一产品将会在3月3……享誉盛名的传奇耳机全面升级Bose推出全新QuietComf2021年9月29日,中国今日,Bose发布全新QuietComfort45消噪耳机,取代享誉盛名的QuietComfort35,带来即刻安静的全新消噪体验;新增通透模式,一键……求求你,不要再使用!null判空了对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。那么,有什么办法可以避免在代码中写大……
十万年后,如果人类还存在,那么人类简史上会记载哪些事件?早期票房大热三星可折叠手机,我卖不出去,因为我没有苹果称抖动会损坏iPhone摄像头,iPhone12价比老人今天终于入手ipadpro5买小米还是买一加比较好?小米折叠概念新机,1。08亿像素高通骁龙888Plus,整体再狙击小米,联想抢发全球首款骁龙8Plus手机外观配置够顶级闭眼选添可智能洗地机芙万2。0slim芙万2。0LCD你更喜数字人民币碳中和试点扩容大规模切入外卖网购机票火车票等低碳场三星亮5G王牌之作,采用双面屏设计,感觉小米11Ultra不华罗庚解决实际问题如何选购笔记本电脑
学会宽容关于我与诚信作文1300字如果这次12强还是里皮带队,场面与结果会不会更好呢?NASA下一代Spacesuitqq说说夜深了伤感说说男人也那么现实吗?结个婚,还非得锦上添花?世界上有粉色的沙滩吗?这个世界怎么了,为什么最近总遇到类似这种案例,还是屡教不改?【歌词】我的SARA歌手:温兆伦热闻聚热点网 那种运动减肥效果快呢?不吃闷头亏敢反抗职场霸凌的星座科普下初三化学酸碱盐学习方法

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找江西南阳嘉兴昆明铜陵滨州广东西昌常德梅州兰州阳江运城金华广西萍乡大理重庆诸暨泉州安庆南充武汉辽宁