范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

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

  对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。
  那么,有什么办法可以避免在代码中写大量的判空语句呢?
  有人说可以使用 JDK8提供的 Optional 来避免判空,但是用起来还是有些麻烦。
  作者在日常工作中,封装了一个工具,可以可以链式调用对象成员而无需判空,相比原有的if null逻辑 和 JDK8提供的 Optional 更加优雅易用,在工程实践中大大提高了编码效率,也让代码更加的精准和优雅。
  不优雅的判空调用
  我想从事Java开发的小伙伴肯定有遇到过下面这种让人难受的判空逻辑:现在有一个User类,School 是它的成员变量/**  * @author Axin  * @since 2020-09-20  * @summary 一个User类定义   * (Ps:Data 是lombok组件提供的注解,简化了get set等等的约定代码)  */  @Data  public class User {      private String name;      private String gender;      private School school;      @Data      public static class School {          private String scName;          private String adress;      }  } 复制代码
  现在想要获得School的成员变量 adress , 一般的处理方式:public static void main(String[] args) {      User axin = new User();      User.School school = new User.School();      axin.setName("hello");      if (Objects.nonNull(axin) && Objects.nonNull(axin.getSchool())) {          User.School userSc = axin.getSchool();          System.out.println(userSc.getAdress());      }  } 复制代码
  获取adress时要对School进行判空,虽然有些麻烦,到也能用,通过 JDK8 提供的 Optional 工具也是可以,但还是有些麻烦。
  而下文的 OptionalBean 提供一种可以链式不断地调用成员变量而无需判空的方法,直接链式调用到你想要获取的目标变量,而无需担心空指针的问题。
  链式调用成员变量
  如果用了本文设计的工具 OptionalBean ,那么上述的调用可以简化成这样:public static void main(String[] args) {      User axin = new User();      User.School school = new User.School();      axin.setName("hello");      // 1. 基本调用      String value1 = OptionalBean.ofNullable(axin)              .getBean(User::getSchool)              .getBean(User.School::getAdress).get();      System.out.println(value1);  } 复制代码
  执行结果:
  其中User的school变量为空,可以看到代码并没有空指针,而是返回了null。这个工具怎么实现的呢?
  OptionalBean 工具/**  * @author Axin  * @since 2020-09-10  * @summary 链式调用 bean 中 value 的方法  */  public final class OptionalBean {      private static final OptionalBean<?> EMPTY = new OptionalBean<>();      private final T value;      private OptionalBean() {          this.value = null;      }      /**       * 空值会抛出空指针       * @param value       */      private OptionalBean(T value) {          this.value = Objects.requireNonNull(value);      }      /**       * 包装一个不能为空的 bean       * @param value       * @param        * @return       */      public static  OptionalBean of(T value) {          return new OptionalBean<>(value);      }      /**       * 包装一个可能为空的 bean       * @param value       * @param        * @return       */      public static  OptionalBean ofNullable(T value) {          return value == null ? empty() : of(value);      }      /**       * 取出具体的值       * @param fn       * @param        * @return       */      public T get() {          return Objects.isNull(value) ? null : value;      }      /**       * 取出一个可能为空的对象       * @param fn       * @param        * @return       */      public  OptionalBean getBean(Function<? super T, ? extends R> fn) {          return Objects.isNull(value) ? OptionalBean.empty() : OptionalBean.ofNullable(fn.apply(value));      }      /**       * 如果目标值为空 获取一个默认值       * @param other       * @return       */      public T orElse(T other) {          return value != null ? value : other;      }      /**       * 如果目标值为空 通过lambda表达式获取一个值       * @param other       * @return       */      public T orElseGet(Supplier<? extends T> other) {          return value != null ? value : other.get();      }      /**       * 如果目标值为空 抛出一个异常       * @param exceptionSupplier       * @param        * @return       * @throws X       */      public  T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {          if (value != null) {              return value;          } else {              throw exceptionSupplier.get();          }      }      public boolean isPresent() {          return value != null;      }      public void ifPresent(Consumer<? super T> consumer) {          if (value != null)              consumer.accept(value);      }      @Override      public int hashCode() {          return Objects.hashCode(value);      }      /**       * 空值常量       * @param        * @return       */      public static OptionalBean empty() {          @SuppressWarnings("unchecked")          OptionalBean none = (OptionalBean) EMPTY;          return none;      }  } 复制代码
  工具设计主要参考了 Optional 的实现,再加上对链式调用的扩展就是上述的OptionalBean。
  getBean 其实是当变量为空时返回了一个 包装空值的 OptionalBean 对象,同时泛型的使用让工具更加易用。
  使用手册
  可以看到代码中也提供了和 Optional 一样的扩展方法,如 ifPresent()、orElse()等等:public static void main(String[] args) {      User axin = new User();      User.School school = new User.School();      axin.setName("hello");      // 1. 基本调用      String value1 = OptionalBean.ofNullable(axin)              .getBean(User::getSchool)              .getBean(User.School::getAdress).get();      System.out.println(value1);      // 2. 扩展的 isPresent方法 用法与 Optional 一样      boolean present = OptionalBean.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(adress -> System.out.println(String.format("地址存在:%s", adress)));      // 4. 扩展的 orElse      String value2 = OptionalBean.ofNullable(axin)              .getBean(User::getSchool)              .getBean(User.School::getAdress).orElse("家里蹲");      System.out.println(value2);      // 5. 扩展的 orElseThrow      try {          String value3 = OptionalBean.ofNullable(axin)                  .getBean(User::getSchool)                  .getBean(User.School::getAdress).orElseThrow(() -> new RuntimeException("空指针了"));      } catch (Exception e) {          System.out.println(e.getMessage());      }  } 复制代码
  run一下:
  总结
  设计了一种可以链式调用对象成员而无需判空的工具让代码更加的精准和优雅,如果本文设计的工具满足了刚好解决你的困扰,那就在项目中使用吧!

威马W6最实用的无人驾驶智能语音助手大家想必并不陌生,现在无论是手机还是家具都有搭载各式各样的语音助手。汽车自然也不例外。驾驶员驾驶汽车时手扶方向盘,调整车窗或者播放音乐并不那么方便,特别是遇上路况复杂时中止审核情形消除,盛科通信科创板IPO恢复已问询状态4月24日,资本邦了解到,苏州盛科通信股份有限公司(下称盛科通信)科创板IPO恢复已问询状态。图片来源上交所官网盛科通信为国内领先的以太网交换芯片设计企业,主营业务为以太网交换芯片Python知识九大数据类型整数类型简称整型,与数学中整数的概念一致。整型数据的表示方式有4种,分别是十进制二进制(以0B或0b开头)八进制(以0o或0O开头)和十六进制(以0X或0x开头)。使用Python4月全新Adobe2022震撼来袭!PS23。3WinMac版支持M1,一键安装无偿领取提示评论区任意回复私信我关键词ps今日为你精选素材名称Adobe2022全家桶支持系统WinAdobe2022终于来啦体验完新功能觉得既令人大呼过瘾,更令人深思每次的大版本欧盟谈判代表就数字服务法案达成一致品玩4月24日讯,欧盟成员国与欧洲议会的谈判代表当地时间23日就欧盟数字服务法达成一致。该法案要求互联网平台企业采取更多措施删除非法和有害的在线内容,包括仇恨言论虚假信息和假货交易手机,如何猜中我们的心思?手机,如何猜中我们的心思?毫无疑问,手机作为当下最便捷的通讯工具,极大地满足了人们沟通和娱乐需求,几乎成了人们身体的一部分,可谓是随身携带机不离手。但是,您注意到这个现象了吗?我们互联网时代,才更应该清醒发声评论1完美解释了,谣言是怎么来的,以及为什么这么难澄清。评论2分享一个理念沉默的螺旋当人们在发表意见的时候,如果身边都是赞同的观点,或者自己的观点受到大家欢迎,那么表达的积极性会很2022年,华为变了,行动加速中大家都知道,芯片规则修改以后,华为的业务受到了非常严重的影响。简单来讲,华为的三大业务板块分别是通信运营商业务消费者业务和云服务业务。现在,因为芯片规则的限制,华为在海外市场的5G木卫二欧罗巴,可能存在地下湖泊?木卫二欧罗巴,是木星最为重要的卫星之一,欧罗巴表面覆盖有20公里厚的冰层,科学家普遍认为欧罗巴冰层之下是一片海洋,并且由于受到木星的引力作用和地壳摩擦作用,欧罗巴的内海温度和地球海手机的背面美学如今的手机均已进入全面屏时代,正面目前比较流行的就是开孔摄像头的位置有区别,一般都是左上角以及顶面居中设计。所以目前影响手机外观的地方主要是手机背面的设计。目前影响手机的背面美观的满配王炸巨屏,vivo高端商务旗舰上手体验大屏手机之所以深受广大商务人士的青睐,一方面,更大的屏幕可以在处理文件时带来更好的体验,另一方面,手机外观看起来也显得更加大气。因为近几年全面屏的普及,大屏旗舰有很多,但少有定位高
微信8。0。20正式版发布!新功能关系你我他在社交软件领域,可谓是三十年河东,三十年河西。在2011年前基本上就是QQ的天下,它也承载着众多8090的青春岁月。如今的QQ月活跃用户不及微信的一半。如今较为活跃的社交软件莫过于全国机动车保有量突破4亿辆新能源汽车呈高速增长态势中国经济网北京4月8日讯(记者张懿)记者从公安部网站获悉,截至2022年3月底,全国机动车保有量达4。02亿辆,其中汽车3。07亿辆,占机动车总量的76。37新能源汽车保有量达89新能源车会降价么?2022年起,所有的新能源车都不同幅度涨价,而且是连续涨价。那么涨价潮还会继续么?高价格还会持续多久?毕竟我也想干一年首付一辆海豚或者宋Prodmi呢经过一番调查,基本情况如下1涨九安医疗,中青宝,中文在线,中国医药,美盛文化,金种子酒金种子酒是白酒概念。武汉凡谷是通信设备概念。黑牡丹是装配式建筑概念。九安医疗是新冠检测概念。依米康是数据中心概念。三安光电第三代半导体概念。浪潮软件是大数据概念。斯达半导是半导体元新技术渗透率加快,龙头加速扩产电力设备与新能源新技术渗透率加快,龙头加速扩产行业周报202204051本周(2022。03。282022。04。01,下同)观点新技术渗透率加快,龙头加速扩产(1)新能源汽车从销为什么原来5千元以上的手机都抢,现在3千元都嫌贵?并不是因为穷记得前些年刚刚有功能机升级到智能机的时候,只要推出一款新手机,不论是高端机还是低端机,哪怕是5000元以上的高端机型,也会出现抢购一空的情况,甚至出现有的人雨夜排队抢购手机的现象。买对不买贵,这三款旗舰手机大降价,迎来最佳入手时机不知道大家最近有没有换手机的打算呢,相信很多朋友和妖妖一样,面对市场上不断发布的新机,只觉得眼花缭乱,不知道如何选择。不过最近妖妖发现几款旧旗舰机型偷偷降价了,相当值得入手,没想好折叠屏手机刚需很旺,技术却还不成熟深圳知名独角兽企业柔宇科技显然遇到麻烦了,2021年2月科创板上市失败后,柔宇科技的负面信息就逐渐多了起来,这家公司还传出了拖欠员工薪资的消息。2022年清明假期前,柔宇科技又被曝灵魂拷问旗舰手机到底要不要标配长焦镜头,你会怎么选?随着万物互联的5G新时代的到来,影像的记录与分享已经成为了人们生活中不可或缺的需求,手机摄像头的作用也会变得越来越广泛,因此,我们有理由相信能够实现更高倍数的潜望式摄像头和每一代手闺蜜和班花较劲,气得闺蜜摔手机,决定用真我GTNeo3找回面子前几天和闺蜜逛街明显感觉她的情绪不太好,一问才知道她之前参加大学同学聚会,因为手机被班花嘲笑了。我闺蜜和那个班花在大学都属于风云人物,所以避免不了暗中较劲。但是闺蜜更注重学业,所以京东被曝排长队办离职?被裁员工吐露心声没有体面可言京东去年营收高达9516亿元,将华为都远远甩在身后,成功的坐上中国第一民企的座椅。京东的成功并非没有道理,有着完整的电商经济体系和物流体系,可以说京东自身就实现了一条路服务,即便是