聊聊java中一些减少if else 的编码习惯的方法

前言

前段时间在阅读别人所写的代码的时候 , 发现其中一些业务相关的方法体内 , 出现了比较多的if-else语句多层嵌套的情况  . 首先我个人不是不提倡写if-else语句 , 不得不说 , 很多时候 , 在写某些逻辑 使用if-else 去做判断 , 代码看起来还是十分直观的  , 但是如果滥用if-else , 形成多层嵌套或者形成, 其中每个case 还包含了大量的逻辑 , 此时从可读性来说 , 使用if-else就有点得不偿失了 .  而且某些时候 ,  可能并不需这么多的if-else , 或者是可以使用其他编码方式从而达到减少的if-else 的效果  .

减少if-else 的使用的方式有很多 , 例如设计模式层面的策略模式或者是责任链模式 . 而这里跟大家分享一下一些个人在日常编码过程中经常用到的 , 比较简单的  、从编码习惯层面上的方式 , 去一些减少不必要if-else使用 . 由于本人只是一个小菜鸟 , 如果有写得不对的地方 , 恳请批评指正 .

一些减少if-else的编码方式

方式一 : 提前return

首先展示一段代码示例 :

if (condition1) {
  if (condition2) {
    return getSomething();
  } else {
    return 0;
  }
} else {
  return 0;
}

修改后的代码如下 :

//这里最好对这个flag所判断的逻辑补充注释进行描述
boolean flag = !condition1 || (condition1 && !condition2)
if(flag) {
 return 0;
}

if (condition1 && condition2) {
  return getSomething();
}

如果存在已知在某些条件下 , 需要返回固定值的逻辑 , 可以将这部分逻辑抽取为一个独立的 if-else block  , 并置于其他if-else block的前面 , 当符合该特定条件时 , 直接提前 return  固定值 . 这种方式最直接的效果就是降低if-else的嵌套数量 .

方式二 : 使用三目运算符

先上例子 , 这里以一个业务场景为例 :

查询某条评论的图片URL列表 (如果有 , 评论的图片url列表以JSON数组字符串格式保存在评论表中)

修改前的代码如下 :

Comment comment = getById(commentId);

if (Objects.isNull(comment)) {
  throw new RuntimeException("评论不存在或已被删除");
}

String imgListStr = comment.getImgList();
if(StringUtils.isEmpty(imgListStr)) {
  return null;
}

return JSON.parseArray(imgListStr, String.class);

修改后 :

Comment comment = getById(commentId);

if (Objects.isNull(comment)) {
  throw new RuntimeException("评论不存在或已被删除");
}

String imgListStr = comment.getImgList();
return StringUtils.isEmpty(imgListStr)) ?
  null : JSON.parseArray(imgListStr, String.class);

方式三 : 使用Assert断言

在编写业务代码过程中 , 如果需要对某些特定的条件进行判断 , 且当条件不满足时需要抛出异常 . 对于这种场景 , 除了使用上面三目运算符的示例当中的if方式 , 还可以通过使用Spring Framework 给我们提供的 Assert  工具类进行 .
其中常用的API 有 :

  • isTrue(boolean expression , String message) : 当expressio == false时 , 会抛出异常 , 异常的message则为第二个入参 ;
  • void notNull(@Nullable Object object, String message) : 同上 , 当object == null 时 , 会抛出异常;
  • void notEmpty(@Nullable Collection<?> collection, String message) : 同上 , 当集合对象为null或者集合元素为空时 , 会抛出异常 .
  • .....

还有其他较多方法 , 可以直接看源码的解析 , 当然实际上isTrue() 已经够用了 , 如果需要更加的语义化 , 可以使用对应的API .

修改前代码 :

if (Objects.isNull(comment)) {
  throw new RuntimeException("评论不存在或已被删除");
}

修改后代码 :

 Assert.isTrue(Objects.nonNull(comment),"评论不存在或已被删除");
 Assert.notNull(comment,"评论不存在或已被删除");

目前Assert工具方法只能抛出单一一种异常 java.lang.IllegalArgumentException , 如果需要自定义所抛出的异常 , 则该方式不适用 .

方式四 : 使用Optional

Optional是 java8 的新特性 , 相当于一个对象的容器 , 主要用于对象的null值校验 , 以及在进行校验后可链式地进行后续操作 , 如 : 抛出异常、null替换 等  .

其中我个人比较常用的几个方法为 :

  • static <T> Optional<T> ofNullable(T value) :  使用Optional 将对象进行包裹 ;
  • T orElse(T other) :  Optional中的对象为null时 ,返回入参的对象 .
  • T orElseGet(Supplier<? extends T> other) :  Optional中的对象为null时 , 返回Supplier 提供的值 ;
  • T orElseThrow(Supplier<? extends X> exceptionSupplier) :  Optional中的对象为null时 , 抛出supplier提供的自定义异常

代码示例 :

Message message1 = Optional.ofNullable(getById(messageId))
  .orElseThrow(() -> new RuntimeException("消息不存在!"));

Message message2 = Optional.ofNullable(getById(messageId))
  .orElse(new Message());

Message message3 = Optional.ofNullable(getById(messageId))
  .orElseGet(Message::new);

由于我日常需要的进行空值判断的比较多的场景是从数据库查询数据完毕时 , 需要查询结果进行空值判断 . 由于我所在的公司使用的持久层框架是mybatis  , 不像Spirng Boot 2.x 默认版本的JPA 那样DAO层方法支持返回值为Optional , 所以这里如果需要使用Optional , 只能手动去使用上面列举的第一个方法对查询结果进行包装 .

当然 , IDEA其实已经给我们提供了该包装方式的热键了  , 如下图所示 :

结语

个人的一些减少if-else 编码习惯分享就这里了 , 这几种方式里面 , 我个人觉得效果最明显的还是第一种 提前return , 很多时候 , 提前return 也可以很好降低一段代码的复杂度 .

当然如果必须要使用大量的if-else 去控制逻辑时 , 在每个condition 标明一下注释还是一个挺不错的习惯 .

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java的if else语句入门指南(推荐)

    条件语句,是程序中根据条件是否成立进行选择执行的一类语句,这类语句在实际使用中,难点在于如何准确的抽象条件.例如实现程序登录功能时,如果用户名和密码正确,则进入系统,否则弹出"密码错误"这样的提示框等. 本部分对于条件语句的介绍,重点在于语法讲解和基本的使用,更详细的使用参看后续的综合示例部分. 在Java语言中,条件语句主要有两类语法:if语句和switch语句. 1 .if语句 if关键字中文意思是如果,其细致的语法归纳来说总共有三种:if语句.if-else语句和if-else

  • Java编程细节重构之为什么if-else不是好代码详析

    前言 面向过程设计和面向对象设计的主要区别是:是否在业务逻辑层使用冗长的if else判断.如果你还在大量使用if else,当然,界面表现层除外,即使你使用Java/C#这样完全面向对象的语言,也只能说明你的思维停留在传统的面向过程语言上.本文将通过示例代码给大家介绍关于Java编程细节重构之if-else的相关内容,下面来一起看看详细的介绍吧 平时开发中if-else用的多吗? 其实这是个再正常不过的coding习惯,当我们代码量小的时候用来做条件判断是再简单不过的了. 但对于优秀程序员来说

  • Java的Struts框架中的if/else标签使用详解

    这些标签执行可在每一种语言找到的一种基本条件流程. 'If'标签可用于本身或与"Else If''标签和/或单/多'Else'标签,如下图所示: <s:if test="%{false}"> <div>Will Not Be Executed</div> </s:if> <s:elseif test="%{true}"> <div>Will Be Executed</div>

  • Java中if...else语句使用的学习教程

    if语句 一个if语句包含一个布尔表达式和一条或多条语句. 语法 If语句的用语法如下: if(布尔表达式) {    //如果布尔表达式为true将执行的语句 } 如果布尔表达式的值为true,则执行if语句中的代码块.否则执行If语句块后面的代码. public class Test { public static void main(String args[]){ int x = 10; if( x < 20 ){ System.out.print("这是 if 语句");

  • Java基础教程_判断语句if else

    与三元运算符相比: 好处:可以简化if else 代码 弊端 因为是一个运算符,所以运算玩必须要有一个结果 以上这篇Java基础教程_判断语句if else就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • 详解Java编程中if...else语句的嵌套写法

    if...else if...else语句 if语句后面可以跟elseif-else语句,这种语句可以检测到多种可能的情况. 使用if,else if,else语句的时候,需要注意下面几点: if语句至多有1个else语句,else语句在所有的elseif语句之后. If语句可以有若干个elseif语句,它们必须在else语句之前. 一旦其中一个else if语句检测为true,其他的else if以及else语句都将跳过执行. 语法 if...else语法格式如下: if(布尔表达式 1){

  • 聊聊java中一些减少if else 的编码习惯的方法

    前言 前段时间在阅读别人所写的代码的时候 , 发现其中一些业务相关的方法体内 , 出现了比较多的if-else语句多层嵌套的情况  . 首先我个人不是不提倡写if-else语句 , 不得不说 , 很多时候 , 在写某些逻辑 使用if-else 去做判断 , 代码看起来还是十分直观的  , 但是如果滥用if-else , 形成多层嵌套或者形成, 其中每个case 还包含了大量的逻辑 , 此时从可读性来说 , 使用if-else就有点得不偿失了 .  而且某些时候 ,  可能并不需这么多的if-el

  • 一起聊聊Java中13种锁的实现方式

    目录 1.悲观锁 2.乐观锁 3.分布式锁 加锁 4.可重入锁 5.自旋锁 6.独享锁 7.共享锁 8.读锁/写锁 9.公平锁/非公平锁 10.可中断锁/不可中断锁 11.分段锁 12.锁升级(无锁|偏向锁|轻量级锁|重量级锁) 无锁 偏向锁 轻量级锁 重量级锁 13.锁优化技术(锁粗化.锁消除) 最近有很多小伙伴给我留言,分布式系统时代,线程并发,资源抢占,"锁" 慢慢变得很重要.那么常见的锁都有哪些? 今天Tom哥就和大家简单聊聊这个话题. 1.悲观锁 正如其名,它是指对数据修改时

  • 聊聊Java 中的线程中断

    Java如何实现线程中断? 通过调用Thread类的实例方法interrupt.如下: Thread thread = new Thread(){ @Override public void run() { if(isInterrupted()){ System.out.println("interrupt"); } } }; thread.start(); thread.interrupt(); 线程中断后线程会立即停止执行吗? NO. 而如果线程未阻塞,或未关心中断状态,则线程会正

  • 一起聊聊Java中的自定义异常

    目录 Java中的异常 自定义Java异常类 Java异常源码 在学习Java的过程中,想必大家都一定学习过异常这个篇章,异常的基本特性和使用这里就不再多讲了.想必大家都能够理解看懂,并正确使用. 但是,光学会基本异常处理和使用不够的,在工作中常会有自定义业务异常的场景,根据不同的业务异常做对应异常处理,出现异常并不可怕,有时候是需要使用异常来驱动业务的处理,例如: 在使用唯一约束的数据库的时候,如果插入一条重复的数据,那么可以通过捕获唯一约束异常DuplicateKeyException,如果

  • 在java中实现C#语法里的按引用传递参数的方法

    在C#中,在次函数中调用时改变了其中的数值,主函数中也将发生改变 ref 关键字使参数按引用传递.其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中.若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字 out 关键字会导致参数通过引用来传递.这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化.若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字. Java里面不像C#那样,Java只有对象类

  • java中的equals()和toString()方法实例详解

    java中的equals()和toString()方法 , 这里写个小例子帮助大家学习理解此部分知识. /* 所有对象的父类Object Object中的方法: equals() 对象是否相同的比较方法 toString()对象的字符串表现形式 */ class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } } class ObjectDemo {

  • Java 中二进制转换成十六进制的两种实现方法

    Java 中二进制转换成十六进制的两种实现方法 每个字节转成16进制,方法1 /** * 每个字节转成16进制,方法1 * * @param result */ private static String toHex(byte[] result) { StringBuffer sb = new StringBuffer(result.length * 2); for (int i = 0; i < result.length; i++) { sb.append(Character.forDigi

  • 详解Java中String类型与默认字符编码

    为什么写这个 至于为什么要写这个,主要是一句mmp一定要讲,绕了一上午,晕死 Java程序中的中文乱码问题一直是一个困扰程序员的难题,自己也不例外,早在做项目时就遇到过很多编码方式的坑,当时想填来着,但是嫌麻烦.这次终于忍不住了,一定要弄个明白 String类型的编码方式 从网上查的资料都说,Java默认的字符编码是Unicode,而String类型的编码方式是与JVM编码方式和本机操作系统默认字符集有关的.于是我做出了测试 在Java中可以这样显示查看本地编码方式(JVM还是OS呢?) //

  • 详解Java中NullPointerException异常的原因详解以及解决方法

    NullPointerException是当您尝试使用指向内存中空位置的引用(null)时发生的异常,就好像它引用了一个对象一样. 当我们声明引用变量(即对象)时,实际上是在创建指向对象的指针.考虑以下代码,您可以在其中声明基本类型的整型变量x: int x; x = 10; 在此示例中,变量x是一个整型变量,Java将为您初始化为0.当您在第二行中将其分配给10时,值10将被写入x指向的内存中. 但是,当您尝试声明引用类型时会发生不同的事情.请使用以下代码: Integer num; num

  • 浅谈Java中Collections.sort对List排序的两种方法

    目录 一.Collections.sort的简单使用 二.问题提出 三.Comparable实现排序 四.Comparator实现排序 五.Comparable 与Comparator区别 一.Collections.sort的简单使用 说到List的排序,第一反应当然是使用Collections.sort,方便简单.下面实现一下~~ private void sortStrings() { List<String> list = new ArrayList<String>();

随机推荐