Java中控制流程语句的深入讲解

作者:初念初恋 时间:2022-07-21 15:29:25 

目录
  • 前言

  • if-then

  • if-then-else

  • switch

  • 使用 String

  • while

  • do-while

  • for

  • break

  • continue

  • return

  • 总结

前言

流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。

控制语句分为三类:顺序、选择和循环。

顺序结构:代表“先执行a,再执行b”的逻辑。

选择结构:代表“如果…,则…”的逻辑。

循环结构:代表“如果…,则重复执行…”的逻辑。

实际上,任何软件和程序,小到一个练习,大到一个操作系统,本质上都是由“变量、选择语句、循环语句”组成。
这三种基本逻辑结构是相互支撑的,它们共同构成了算法的基本结构,无论怎样复杂的逻辑结构,都可以通过它们来表达。

if-then

它告诉你要只有 if 后面是 true 时才执行特定的代码。


void applyBrakes() {
   // the "if" clause: bicycle must be moving
   if (isMoving){
       // the "then" clause: decrease current speed
       currentSpeed--;
   }
}

如果 if 后面是 false, 则跳到 if-then 语句后面。语句可以省略中括号,但在编码规范里面不推荐使用,如:


void applyBrakes() {
   // same as above, but without braces
   if (isMoving)
       currentSpeed--;
}

if-then-else

该语句是在 if 后面是 false 时,提供了第二个执行路径。


void applyBrakes() {
   if (isMoving) {
       currentSpeed--;
   } else {
       System.err.println("The bicycle has already stopped!");
   }
}

下面是一个完整的例子:


class IfElseDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       int testscore = 76;
       char grade;

if (testscore >= 90) {
           grade = 'A';
       } else if (testscore >= 80) {
           grade = 'B';
       } else if (testscore >= 70) {
           grade = 'C';
       } else if (testscore >= 60) {
           grade = 'D';
       } else {
           grade = 'F';
       }
       System.out.println("Grade = " + grade);
   }
}

输出为:Grade = C

switch

switch 语句可以有许多可能的执行路径。可以使用 byte, short, char, 和 int 基本数据类型,也可以是枚举类型(enumerated types)、String 以及少量的原始类型的包装类 Character, Byte, Short, 和 Integer。

下面是一个 SwitchDemo 例子:


class SwitchDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       int month = 8;
       String monthString;
       switch (month) {
       case 1:
           monthString = "January";
           break;
       case 2:
           monthString = "February";
           break;
       case 3:
           monthString = "March";
           break;
       case 4:
           monthString = "April";
           break;
       case 5:
           monthString = "May";
           break;
       case 6:
           monthString = "June";
           break;
       case 7:
           monthString = "July";
           break;
       case 8:
           monthString = "August";
           break;
       case 9:
           monthString = "September";
           break;
       case 10:
           monthString = "October";
           break;
       case 11:
           monthString = "November";
           break;
       case 12:
           monthString = "December";
           break;
       default:
           monthString = "Invalid month";
           break;
       }
       System.out.println(monthString);
   }
}

break 语句是为了防止 fall through。


class SwitchDemoFallThrough {

/**
    * @param args
    */
   public static void main(String[] args) {
       java.util.ArrayList<String> futureMonths = new java.util.ArrayList<String>();

int month = 8;

switch (month) {
       case 1:
           futureMonths.add("January");
       case 2:
           futureMonths.add("February");
       case 3:
           futureMonths.add("March");
       case 4:
           futureMonths.add("April");
       case 5:
           futureMonths.add("May");
       case 6:
           futureMonths.add("June");
       case 7:
           futureMonths.add("July");
       case 8:
           futureMonths.add("August");
       case 9:
           futureMonths.add("September");
       case 10:
           futureMonths.add("October");
       case 11:
           futureMonths.add("November");
       case 12:
           futureMonths.add("December");
           break;
       default:
           break;
       }

if (futureMonths.isEmpty()) {
           System.out.println("Invalid month number");
       } else {
           for (String monthName : futureMonths) {
               System.out.println(monthName);
           }
       }
   }

}

输出为:

August
September
October
November
December

技术上来说,最后一个 break 并不是必须,因为流程跳出 switch 语句。但仍然推荐使用 break ,主要修改代码就会更加简单和防止出错。default 处理了所有不明确值的情况。

下面例子展示了一个局域多个 case 的情况。


class SwitchDemo2 {

/**
    * @param args
    */
   public static void main(String[] args) {
       int month = 2;
       int year = 2000;
       int numDays = 0;

switch (month) {
       case 1:
       case 3:
       case 5:
       case 7:
       case 8:
       case 10:
       case 12:
           numDays = 31;
           break;
       case 4:
       case 6:
       case 9:
       case 11:
           numDays = 30;
           break;
       case 2:
           if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0))
               numDays = 29;
           else
               numDays = 28;
           break;
       default:
           System.out.println("Invalid month.");
           break;
       }
       System.out.println("Number of Days = " + numDays);
   }
}

输出为:Number of Days = 29

使用 String

Java SE 7 开始,可以在 switch 语句里面使用 String,下面是一个例子


class StringSwitchDemo {

public static int getMonthNumber(String month) {

int monthNumber = 0;

if (month == null) {
           return monthNumber;
       }

switch (month.toLowerCase()) {
       case "january":
           monthNumber = 1;
           break;
       case "february":
           monthNumber = 2;
           break;
       case "march":
           monthNumber = 3;
           break;
       case "april":
           monthNumber = 4;
           break;
       case "may":
           monthNumber = 5;
           break;
       case "june":
           monthNumber = 6;
           break;
       case "july":
           monthNumber = 7;
           break;
       case "august":
           monthNumber = 8;
           break;
       case "september":
           monthNumber = 9;
           break;
       case "october":
           monthNumber = 10;
           break;
       case "november":
           monthNumber = 11;
           break;
       case "december":
           monthNumber = 12;
           break;
       default:
           monthNumber = 0;
           break;
       }

return monthNumber;
   }

public static void main(String[] args) {

String month = "August";

int returnedMonthNumber = StringSwitchDemo.getMonthNumber(month);

if (returnedMonthNumber == 0) {
           System.out.println("Invalid month");
       } else {
           System.out.println(returnedMonthNumber);
       }
   }
}

输出为:8

注:switch 语句表达式中不能有 null。

while

while 语句在判断条件是 true 时执行语句块。语法如下:


while (expression) {
    statement(s)
}

while 语句计算的表达式,必须返回 boolean 值。如果表达式计算为 true,while 语句执行 while 块的所有语句。while 语句继续测试表达式,然后执行它的块,直到表达式计算为 false。完整的例子:


class WhileDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       int count = 1;
       while (count < 11) {
           System.out.println("Count is: " + count);
           count++;
       }
   }
}

用 while 语句实现一个无限循环:


while (true){
   // your code goes here
}

do-while

语法如下:


do {
    statement(s)
} while (expression);

do-while 语句和 while 语句的区别是,do-while 计算它的表达式是在循环的底部,而不是顶部。所以,do 块的语句,至少会执行一次,如 DoWhileDemo 程序所示:


class DoWhileDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       int count = 1;
       do {
           System.out.println("Count is: " + count);
           count++;
       } while (count < 11);
   }
}

输出为:

Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10

for

for 语句提供了一个紧凑的方式来遍历一个范围值。程序经常引用为"for 循环",因为它反复循环,直到满足特定的条件。for 语句的通常形式,表述如下:


for (initialization; termination;
    increment) {
   statement(s)
}

使 for 语句时要注意:

  • initialization 初始化循环;它执行一次作为循环的开始。

  • 当 termination 计算为 false,循环结束。

  • increment 会在循环的每次迭代执行;该表达式可以接受递增或者递减的值


class ForDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       for(int i=1; i<11; i++){
           System.out.println("Count is: " + i);
      }
   }

}

输出为:

Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10

注意:代码在 initialization 声明变量。该变量的存活范围,从它的声明到 for 语句的块的结束。所以,它可以用在 termination 和 increment。如果控制 for 语句的变量,不需要在循环外部使用,最好是在 initialization 声明。经常使用 i,j,k 经常用来控制 for 循环。在 initialization 声明他们,可以限制他们的生命周期,减少错误。

for 循环的三个表达式都是可选的,一个无限循环,可以这么写:


// infinite loop
for ( ; ; ) {

// your code goes here
}

for 语句还可以用来迭代 集合(Collections) 和 数组(arrays),这个形式有时被称为增强的 for 语句( enhanced for ),可以用来让你的循环更加紧凑,易于阅读。为了说明这一点,考虑下面的数组:


int[] numbers = {1,2,3,4,5,6,7,8,9,10};

使用 增强的 for 语句来循环数组


class EnhancedForDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       int[] numbers =
           {1,2,3,4,5,6,7,8,9,10};
       for (int item : numbers) {
           System.out.println("Count is: " + item);
       }
   }

}

输出:

Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10

尽可能使用这种形式的 for 替代传统的 for 形式。

break

break 语句有两种形式:标签和非标签。在前面的 switch 语句,看到的 break 语句就是非标签形式。可以使用非标签 break 用来结束 for,while,do-while 循环,如下面的 BreakDemo 程序:


class BreakDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 };
       int searchfor = 12;

int i;
       boolean foundIt = false;

for (i = 0; i < arrayOfInts.length; i++) {
           if (arrayOfInts[i] == searchfor) {
               foundIt = true;
               break;
           }
       }

if (foundIt) {
           System.out.println("Found " + searchfor + " at index " + i);
       } else {
           System.out.println(searchfor + " not in the array");
       }
   }

}

这个程序在数组终查找数字12。break 语句,当找到值时,结束 for 循环。控制流就跳转到 for 循环后面的语句。程序输出是:

Found 12 at index 4

无标签 break 语句结束最里面的 switch,for,while,do-while 语句。而标签break 结束最外面的语句。接下来的程序,BreakWithLabelDemo,类似前面的程序,但使用嵌套循环在二维数组里寻找一个值。但值找到后,标签 break 语句结束最外面的 for 循环(标签为"search"):


class BreakWithLabelDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       int[][] arrayOfInts = { { 32, 87, 3, 589 }, { 12, 1076, 2000, 8 }, { 622, 127, 77, 955 } };
       int searchfor = 12;

int i;
       int j = 0;
       boolean foundIt = false;

search: for (i = 0; i < arrayOfInts.length; i++) {
           for (j = 0; j < arrayOfInts[i].length; j++) {
               if (arrayOfInts[i][j] == searchfor) {
                   foundIt = true;
                   break search;
               }
           }
       }

if (foundIt) {
           System.out.println("Found " + searchfor + " at " + i + ", " + j);
       } else {
           System.out.println(searchfor + " not in the array");
       }
   }
}

程序输出是:

Found 12 at 1, 0

break 语句结束标签语句,它不是传送控制流到标签处。控制流传送到紧随标记(终止)声明。

注: Java 没有类似于 C 语言的 goto 语句,但带标签的 break 语句,实现了类似的效果。

continue

continue 语句忽略 for,while,do-while 的当前迭代。非标签模式,忽略最里面的循环体,然后计算循环控制的 boolean 表达式。接下来的程序,ContinueDemo,通过一个字符串的步骤,计算字母“p”出现的次数。如果当前字符不是 p,continue 语句跳过循环的其他代码,然后处理下一个字符。如果当前字符是 p,程序自增字符数。


class ContinueDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       String searchMe = "peter piper picked a " + "peck of pickled peppers";
       int max = searchMe.length();
       int numPs = 0;

for (int i = 0; i < max; i++) {
           // interested only in p's
           if (searchMe.charAt(i) != 'p')
               continue;

// process p's
           numPs++;
       }
       System.out.println("Found " + numPs + " p's in the string.");
   }

}

程序输出:

Found 9 p's in the string

为了更清晰看效果,尝试去掉 continue 语句,重新编译。再跑程序,count 将是错误的,输出是 35,而不是 9.
带标签的 continue 语句忽略标签标记的外层循环的当前迭代。下面的程序例子,ContinueWithLabelDemo,使用嵌套循环在字符传的字串中搜索字串。需要两个嵌套循环:一个迭代字串,一个迭代正在被搜索的字串。下面的程序ContinueWithLabelDemo,使用 continue 的标签形式,忽略最外层的循环。


class ContinueWithLabelDemo {

/**
    * @param args
    */
   public static void main(String[] args) {
       String searchMe = "Look for a substring in me";
       String substring = "sub";
       boolean foundIt = false;

int max = searchMe.length() - substring.length();

test: for (int i = 0; i <= max; i++) {
           int n = substring.length();
           int j = i;
           int k = 0;
           while (n-- != 0) {
               if (searchMe.charAt(j++) != substring.charAt(k++)) {
                   continue test;
               }
           }
           foundIt = true;
           break test;
       }
       System.out.println(foundIt ? "Found it" : "Didn't find it");
   }

}

这里是程序输出:

Found it

return

最后的分支语句是 return 语句。return 语句从当前方法退出,控制流返回到方法调用处。return 语句有两种形式:一个是返回值,一个是不返回值。为了返回一个值,简单在 return 关键字后面把值放进去(或者放一个表达式计算)。


return ++count;

return 的值的数据类型,必须和方法声明的返回值的类型符合。当方法声明为 void,使用下面形式的 return 不需要返回值。


return;

来源:https://juejin.cn/post/7021026073345261598

标签:java,流程,控制
0
投稿

猜你喜欢

  • 基于Spring Security前后端分离的权限控制系统问题

    2022-10-16 21:32:39
  • Android Flutter中Offstage组件的使用教程详解

    2023-08-20 01:01:44
  • SpringCloud远程服务调用实战笔记

    2022-07-13 06:40:19
  • 利用Spring Boot操作MongoDB的方法教程

    2023-11-29 11:14:27
  • 解决SpringBoot web项目启动后立即关闭的问题

    2023-07-26 02:33:37
  • Java使用自动化部署工具Gradle中的任务设定教程

    2022-08-09 12:13:31
  • Java AQS信号量Semaphore的使用

    2021-06-11 17:10:44
  • Android App获取屏幕旋转角度的方法

    2021-12-26 10:42:19
  • Spring Security OAuth2 实现登录互踢的示例代码

    2023-09-04 19:09:28
  • 运行java的class文件方法详解

    2021-07-29 03:53:48
  • go打包aar及flutter调用aar流程详解

    2023-06-24 17:39:21
  • Android如何基于坐标对View进行模拟点击事件详解

    2021-09-24 06:27:30
  • Java使用CountDownLatch实现网络同步请求的示例代码

    2022-04-23 18:40:52
  • Java中的动态和静态编译实例详解

    2021-07-30 15:25:10
  • Java JDK 二分法 分析demo(推荐)

    2022-02-28 23:29:21
  • spring定时任务执行两次及tomcat部署缓慢问题的解决方法

    2022-12-27 09:53:25
  • Java中值类型和引用类型详解

    2023-11-29 00:44:51
  • 如何修改FeginCilent定义的服务名到指定服务

    2022-07-05 05:49:05
  • Java线程的五种状态介绍

    2023-06-16 01:22:15
  • SpringMVC中Controller类数据响应的方法

    2021-10-07 21:00:08
  • asp之家 软件编程 m.aspxhome.com