本固枝荣 —— Java关键字之程序流程控制

Java程序的流程控制语句有:顺序语句、分支语句、循环语句。正常情况下,代码是逐条的按顺序的执行,但是为了能够控制执行满足条件的代码,会加入像if-else分支条件语句、switch多重选择语句、循环语句(如while循环、do-while循环、for循环等)等流程控制语句。

分支语句和循环语句的用法也比较简单,这里着重分析需要注意的一些细节。

if条件语句

if条件语句用到的关键字有:if、else 。

  • 在jdk源码里经常可以看到,if条件后只有一条语句时,会省略{},这样是不符合书写规范的,但也是正确的写法,而多条语句时一定要使用{};
  • if- else if - else结构的语句在代码中书写过多时显得很臃肿,根据实际情况使用三目运算符,或者工具类替代过多的if条件判断;
  • if条件编译是一种Java语法糖,条件编译的实现是根据布尔值的真假,编译器会将不成立的分支消除掉,这一阶段会在编译器解语法糖阶段完成(即编译器会还原最原始的基础语法结构)。举例说明:
// TestIf.java的源码
public class TestIf{
   public static void main(String[] args) {
      if(true){
         System.out.print("1111");
      }else{
         System.out.print("2222");
      }
      if(false){
         System.out.print("33333");
      }else{
         System.out.print("444444");
      }
   }
}

// 经过编译器编译后生成的class文件,TestIf.class
public class TestIf{
  public static void main(String[] paramArrayOfString) {
    System.out.print("1111");
    System.out.print("444444");
  }
}

switch多重选择语句

switch多重选择语句用到的关键字有:switch、case、break、default 。

  • case子句后无break,会按顺序执行下一个case子句,直到遇到break为止,或者执行到最后的default语句为止;
  • break用于循环语句或switch多重选择语句,用于跳出并终止当前循环 或 跳出当前case子句并终止继续往下一个子句执行;
  • switch语句的演变历史:case条件在Java5之前仅支持int、byte、short、char等及对应的包装类等类型,Java5时开始支持枚举类型,Java7时开始支持String类型,Java12开始出现预览版(即当前版本会有该功能,后续版本不一定会有,若实现的效果不理想则会在后续版本中被移除)到Java14正式确定为标准版,大致的功能是使用 -> 符号替换掉case子句中的 : 和 break; 。
  • 值得注意的是,Java12~Java14还确定了yield关键字的作用,为了避免break跳出子句引发的歧义,用yield返回case子句或default子句的值,举例说明这个已经确定的标准版功能:
// Java12之前的switch语句
public class TestSwitch{
    public static void main(String[] args) {
        //测试
        System.out.println("我喜欢的颜色是:" + selectColor(ColorEnum.BLUE));
    }
    private static COLOR selectColor(COLOREnum color) {
        switch (color) {
            case RED:
                color = ColorEnum.RED;    break;
            case YELLOW:
                color = ColorEnum.YELLOW;    break;
            case BLUE:
                color = ColorEnum.BLUE;    break;
            default:
                color = ColorEnum.DUCK;
        }
        return color;
    }
}

// Java12之后的预览版和标准版
public class TestSwitch14{
    public static void main(String[] args) {
        //测试
        System.out.println("我喜欢的颜色是:" + selectColor(ColorEnum.BLUE));
    }
    private static COLOR selectColor(COLOREnum color) {
        color = switch (color) {
            case RED ->  yield ColorEnum.RED;
            case YELLOW -> yield ColorEnum.YELLOW;
            case BLUE -> yield ColorEnum.BLUE;
            default -> color = ColorEnum.DUCK;
        };
        return color;
    }
}

循环语句

循环语句用到的关键字有:do、while、for、break、continue 。

  • while循环语句特点是满足while条件才能进入循环,而do-while循环语句特点是无论while条件是否满足都要执行一次do语句块内的语句;
  • Java中for循环语句有fori、forr、foreach、迭代器等形式,而foreach循环增强也是一种Java语法糖,编译器编译时是通过迭代器实现循环增强的,举例说明:
// TestFor.java源码
public class TestFor{
   public static void main(String[] args) {
      List<String> list = Arrays.asList("I", "am", "xxwei", "3");
      String name = "";
      for (String str : list) {
         name += str;
      }
      System.out.print(name);
   }
}

// TestFor.class字节码
public class  TestFor{
  public static void main(String[] args) {
    List<String> list = Arrays.asList("I", "am", "xxwei", "3");
    String name = "";

    String str;
    for(Iterator var3 = list.iterator();var3.hasNext();name = name + str) {
        str = (String)var3.next();
    }

    System.out.print(name);
    }
}
  • break与continue在循环语句中的区别在于:break 跳出并终止当前循环 ,continue 则是跳出当前循环进入下一次循环;而break与continue 是如何跳出嵌套循环的呢?(使用标记进行跳出循环),最近在看jdk源码,以String类源码中的toLowerCase()方法和lastIndexOf()方法举例:
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

    // lastIndexOf()方法:从后往前查找给定字符串中,第一个出現的位置
    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount, int fromIndex) {
        
        // 参数检查
        int rightIndex = sourceCount - targetCount;
        ...;

        int strLastIndex = targetOffset + targetCount - 1;
        char strLastChar = target[strLastIndex];
        int min = sourceOffset + targetCount - 1;
        int i = min + fromIndex;

    // 标记continue跳至的位置
    startSearchForLastChar:
        while (true) {
            while (i >= min && source[i] != strLastChar) {
                i--;
            }
            if (i < min) {
                return -1;
            }
            int j = i - 1;
            int start = j - (targetCount - 1);
            int k = strLastIndex - 1;

            while (j > start) {
                if (source[j--] != target[k--]) {
                    i--;
                    continue startSearchForLastChar;  //跳至标记处,从外层while继续下一次循环
                }
            }
            return start - sourceOffset + 1;
        }
    }

    // toLowerCase():转小写
    public String toLowerCase(Locale locale) {
        ...;
        int firstUpper;
        final int len = value.length;

        // 标记break跳至的位置
        scan: {
            for (firstUpper = 0 ; firstUpper < len; ) {
                char c = value[firstUpper];
                if ((c >= Character.MIN_HIGH_SURROGATE)
                        && (c <= Character.MAX_HIGH_SURROGATE)) {
                    int supplChar = codePointAt(firstUpper);
                    if (supplChar != Character.toLowerCase(supplChar)) {
                        break scan; //跳至标记处,跳出并终止所有循环
                    }
                    firstUpper += Character.charCount(supplChar);
                } else {
                    if (c != Character.toLowerCase(c)) {
                        break scan; //跳至标记处,,跳出并终止所有循环
                    }
                    firstUpper++;
                }
            }
            return this;
        }

        ...;
        return new String(result, 0, len + resultOffset);
    }
}

总结一下

Java程序流程控制语句需要关注的细节还是挺多的,尤其是普遍的Java语法糖现象(if条件编译、switch支持字符串类型、foreach循环增强等)和Java新版本出现的特性。如今的Java版本迭代周期真的是神速,貌似每半年一个版本,新知识点层出不穷,要求作为技术人需要经常保持学习,让自己跟上技术的发展和变化。

从目前Oracle官方公布的计划表可以看出,Java8和Java11是LTS的(即长期维护的版本),也就是说Java8和Java11已经成为我们必备的技能了。不积硅步无以至千里,点滴付出终将有所收获,共同进步 ~。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值