Java中控制流程語句的深入講解
前言
流程控制語句是用來控制程序中各語句執(zhí)行順序的語句,可以把語句組合成能完成一定功能的小邏輯模塊。
控制語句分為三類:順序、選擇和循環(huán)。
順序結(jié)構(gòu):代表“先執(zhí)行a,再執(zhí)行b”的邏輯。
選擇結(jié)構(gòu):代表“如果…,則…”的邏輯。
循環(huán)結(jié)構(gòu):代表“如果…,則重復(fù)執(zhí)行…”的邏輯。
實際上,任何軟件和程序,小到一個練習(xí),大到一個操作系統(tǒng),本質(zhì)上都是由“變量、選擇語句、循環(huán)語句”組成。
這三種基本邏輯結(jié)構(gòu)是相互支撐的,它們共同構(gòu)成了算法的基本結(jié)構(gòu),無論怎樣復(fù)雜的邏輯結(jié)構(gòu),都可以通過它們來表達(dá)。
if-then
它告訴你要只有 if 后面是 true 時才執(zhí)行特定的代碼。
void applyBrakes() {
// the "if" clause: bicycle must be moving
if (isMoving){
// the "then" clause: decrease current speed
currentSpeed--;
}
}
如果 if 后面是 false, 則跳到 if-then 語句后面。語句可以省略中括號,但在編碼規(guī)范里面不推薦使用,如:
void applyBrakes() {
// same as above, but without braces
if (isMoving)
currentSpeed--;
}
if-then-else
該語句是在 if 后面是 false 時,提供了第二個執(zhí)行路徑。
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 語句可以有許多可能的執(zhí)行路徑??梢允褂?byte, short, char, 和 int 基本數(shù)據(jù)類型,也可以是枚舉類型(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
技術(shù)上來說,最后一個 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 語句表達(dá)式中不能有 null。
while
while 語句在判斷條件是 true 時執(zhí)行語句塊。語法如下:
while (expression) {
statement(s)
}
while 語句計算的表達(dá)式,必須返回 boolean 值。如果表達(dá)式計算為 true,while 語句執(zhí)行 while 塊的所有語句。while 語句繼續(xù)測試表達(dá)式,然后執(zhí)行它的塊,直到表達(dá)式計算為 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 語句實現(xiàn)一個無限循環(huán):
while (true){
// your code goes here
}
do-while
語法如下:
do {
statement(s)
} while (expression);
do-while 語句和 while 語句的區(qū)別是,do-while 計算它的表達(dá)式是在循環(huán)的底部,而不是頂部。所以,do 塊的語句,至少會執(zhí)行一次,如 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 語句提供了一個緊湊的方式來遍歷一個范圍值。程序經(jīng)常引用為"for 循環(huán)",因為它反復(fù)循環(huán),直到滿足特定的條件。for 語句的通常形式,表述如下:
for (initialization; termination;
increment) {
statement(s)
}
使 for 語句時要注意:
- initialization 初始化循環(huán);它執(zhí)行一次作為循環(huán)的開始。
- 當(dāng) termination 計算為 false,循環(huán)結(jié)束。
- increment 會在循環(huán)的每次迭代執(zhí)行;該表達(dá)式可以接受遞增或者遞減的值
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 語句的塊的結(jié)束。所以,它可以用在 termination 和 increment。如果控制 for 語句的變量,不需要在循環(huán)外部使用,最好是在 initialization 聲明。經(jīng)常使用 i,j,k 經(jīng)常用來控制 for 循環(huán)。在 initialization 聲明他們,可以限制他們的生命周期,減少錯誤。
for 循環(huán)的三個表達(dá)式都是可選的,一個無限循環(huán),可以這么寫:
// infinite loop
for ( ; ; ) {
// your code goes here
}
for 語句還可以用來迭代 集合(Collections) 和 數(shù)組(arrays),這個形式有時被稱為增強(qiáng)的 for 語句( enhanced for ),可以用來讓你的循環(huán)更加緊湊,易于閱讀。為了說明這一點,考慮下面的數(shù)組:
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
使用 增強(qiáng)的 for 語句來循環(huán)數(shù)組
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 替代傳統(tǒng)的 for 形式。
break
break 語句有兩種形式:標(biāo)簽和非標(biāo)簽。在前面的 switch 語句,看到的 break 語句就是非標(biāo)簽形式??梢允褂梅菢?biāo)簽 break 用來結(jié)束 for,while,do-while 循環(huán),如下面的 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");
}
}
}
這個程序在數(shù)組終查找數(shù)字12。break 語句,當(dāng)找到值時,結(jié)束 for 循環(huán)??刂屏骶吞D(zhuǎn)到 for 循環(huán)后面的語句。程序輸出是:
Found 12 at index 4
無標(biāo)簽 break 語句結(jié)束最里面的 switch,for,while,do-while 語句。而標(biāo)簽break 結(jié)束最外面的語句。接下來的程序,BreakWithLabelDemo,類似前面的程序,但使用嵌套循環(huán)在二維數(shù)組里尋找一個值。但值找到后,標(biāo)簽 break 語句結(jié)束最外面的 for 循環(huán)(標(biāo)簽為"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 語句結(jié)束標(biāo)簽語句,它不是傳送控制流到標(biāo)簽處??刂屏鱾魉偷骄o隨標(biāo)記(終止)聲明。
注: Java 沒有類似于 C 語言的 goto 語句,但帶標(biāo)簽的 break 語句,實現(xiàn)了類似的效果。
continue
continue 語句忽略 for,while,do-while 的當(dāng)前迭代。非標(biāo)簽?zāi)J?,忽略最里面的循環(huán)體,然后計算循環(huán)控制的 boolean 表達(dá)式。接下來的程序,ContinueDemo,通過一個字符串的步驟,計算字母“p”出現(xiàn)的次數(shù)。如果當(dāng)前字符不是 p,continue 語句跳過循環(huán)的其他代碼,然后處理下一個字符。如果當(dāng)前字符是 p,程序自增字符數(shù)。
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.
帶標(biāo)簽的 continue 語句忽略標(biāo)簽標(biāo)記的外層循環(huán)的當(dāng)前迭代。下面的程序例子,ContinueWithLabelDemo,使用嵌套循環(huán)在字符傳的字串中搜索字串。需要兩個嵌套循環(huán):一個迭代字串,一個迭代正在被搜索的字串。下面的程序ContinueWithLabelDemo,使用 continue 的標(biāo)簽形式,忽略最外層的循環(huán)。
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 語句從當(dāng)前方法退出,控制流返回到方法調(diào)用處。return 語句有兩種形式:一個是返回值,一個是不返回值。為了返回一個值,簡單在 return 關(guān)鍵字后面把值放進(jìn)去(或者放一個表達(dá)式計算)。
return ++count;
return 的值的數(shù)據(jù)類型,必須和方法聲明的返回值的類型符合。當(dāng)方法聲明為 void,使用下面形式的 return 不需要返回值。
return;
總結(jié)
到此這篇關(guān)于Java中控制流程語句的文章就介紹到這了,更多相關(guān)Java控制流程語句內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot登錄攔截器+ThreadLocal實現(xiàn)用戶信息存儲的實例代碼
ThreadLocal 為變量在每個線程中創(chuàng)建了一個副本,這樣每個線程都可以訪問自己內(nèi)部的副本變量,這篇文章主要介紹了springboot登錄攔截器+ThreadLocal實現(xiàn)用戶信息存儲的實例代碼,需要的朋友可以參考下2024-03-03
Spring中事務(wù)管理方案和事務(wù)管理器及事務(wù)控制的API詳解
這篇文章主要介紹了Spring中事務(wù)管理方案和事務(wù)管理器及事務(wù)控制的API詳解,事務(wù)管理是指對事務(wù)進(jìn)行管理和控制,以確保事務(wù)的正確性和完整性,事務(wù)管理的作用是保證數(shù)據(jù)庫的數(shù)據(jù)操作的一致性和可靠性,需要的朋友可以參考下2023-08-08
java?WebSocket?服務(wù)端實現(xiàn)代碼
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動發(fā)送信息給客戶端,這篇文章主要介紹了java?WebSocket?服務(wù)端代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02
springboot項目整合mybatis并配置mybatis中間件的實現(xiàn)
這篇文章主要介紹了springboot項目整合mybatis并配置mybatis中間件的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
解決spring boot網(wǎng)關(guān)gateway導(dǎo)致的坑,無法下載文件問題
這篇文章主要介紹了解決spring boot網(wǎng)關(guān)gateway導(dǎo)致的坑,無法下載文件的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
SpringBoot統(tǒng)一功能處理示例詳解(攔截器)
這篇文章主要介紹了SpringBoot統(tǒng)一功能處理(攔截器),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08
SpringMVC響應(yīng)視圖和結(jié)果視圖詳解
這篇文章主要介紹了SpringMVC響應(yīng)視圖和結(jié)果視圖,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09

