【Java】流程控制

流程控制
- 流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
 - 程序设计中规定的三种流程结构,即:
- 顺序结构
- 程序从上到下逐行地执行,中间没有任何判断和跳转。
 
 - 分支(选择)结构
- 根据条件,选择性地执行某段代码。
 - 有
if-else和switch-case两种分支语句。 
 - 循环结构
- 根据循环条件,重复性的执行某段代码。
 - 有
for、while、do-while三种循环语句。 - JDK5.0 提供了
foreach循环,方便的遍历集合、数组元素。 
 
 - 顺序结构
 
顺序结构
顺序结构就是程序从上到下逐行地执行。表达式语句都是顺序执行的。并且上一行对某个变量的修改对下一行会产生影响。
public class StatementTest{public static void main(String[] args){int x = 1;int y = 2;System.out.println("x = " + x);		System.out.println("y = " + y);	// 对x、y的值进行修改x++;y = 2 * x + y;x = x * 10;	System.out.println("x = " + x);System.out.println("y = " + y);}
}
Java中定义变量时采用合法的前向引用。如:
public static void main(String[] args) {int num1 = 12;int num2 = num1 + 2;
}
// 如下错误
public static void main(String[] args) {int num2 = num1 + 2;int num1 = 12;
}
分支(选择)结构
if-else条件判断结构
1、单分支条件判断:if
if (条件表达式) 语句;
条件表达式必须是布尔表达式(关系表达式或逻辑表达式)或 布尔变量。
int a = 15;
if (a == 15)    // 只有当a等于15时,才会执行下面的打印语句System.out.println("Hello World!");
System.out.println("我是外层");   // if只会对紧跟着的一行代码生效,后续的内容无效
if会进行判断,只有判断成功时才会执行紧跟着的语句,否则会直接跳过。
注意,如果想要在if中执行多行代码,需要使用代码块将这些代码囊括起来。所以说,以后使用if时,如果分支中有多行代码需要执行,就需要添加花括号,如果只有一行代码,花括号可以直接省略,包括else、while、for等语句都是这样的。
if (条件表达式) {语句块;
}
int a = 15;
if (a > 10) {    // 只有判断成功时,才会执行下面的代码块中内容,否则直接跳过System.out.println("a大于10");System.out.println("a的值为:"+a);
}
System.out.println("我是外层");
2、双分支条件判断:if-else
希望判断条件为真时执行某些代码,条件为假时执行另一些代码,可以在后面继续添加else语句。与三元运算符性质比较类似。
if (条件表达式) { 语句块1;
} else {语句块2;
}
if (a > 10) {    // 只有判断成功时,才会执行下面的代码块中内容,否则直接跳过System.out.println("a大于10");System.out.println("a的值为:"+a);
} else {        // 当判断不成功时,会执行else代码块中的代码System.out.println("a小于10");System.out.println("a的值为:"+a);
}
3、多分支条件判断:if-else if-else
需要判断多个分支。一旦条件表达式为true,则进入执行相应的语句块。执行完对应的语句块之后,就跳出当前结构。
if (条件表达式1) {语句块1;
} else if (条件表达式2) {语句块2;
}
...
} else if (条件表达式n) {语句块n;
} else {语句块n+1;
}
public static void main(String[] args) {int score = 62;if (score >= 90)    //90分以上才是优秀System.out.println("优秀");else if (score >= 70)    //当上一级if判断失败时,会继续判断这一级System.out.println("良好");else if (score >= 60)System.out.println("及格");else    //当之前所有的if都判断失败时,才会进入到最后的else语句中System.out.println("不及格");
}
[!IMPORTANT]
当条件表达式之间是“
互斥”关系时(即彼此没有交集),条件判断语句及执行语句间顺序无所谓。当条件表达式之间是“
包含”关系时,“小上大下 / 子上父下”,否则范围小的条件表达式将不可能被执行。
4、if-else 嵌套
在 if 的语句块中,或者是在else语句块中,又包含了另外一个条件判断(可以是单分支、双分支、多分支),就构成了嵌套结构。
(1)如果是嵌套在if语句块中的,只有当外部的if条件满足,才会去判断内部的条件
(2)如果是嵌套在else语句块中的,只有当外部的if条件不满足,进入else后,才会去判断内部的条件
public class NestedIfExample1 {public static void main(String[] args) {int age = 20;boolean hasID = true;// 外部条件:是否有身份证if (hasID) {// 内部条件:年龄是否大于18岁if (age >= 18) {System.out.println("允许进入网吧。");} else {System.out.println("未成年,禁止进入。");}} else {System.out.println("没有身份证,禁止进入。");}}
}
public class NestedIfExample2 {public static void main(String[] args) {int score = 75;if (score >= 90) {System.out.println("成绩优秀!");} else {// 外部条件不满足时,再判断内部条件if (score >= 60) {System.out.println("成绩合格。");} else {System.out.println("成绩不及格。");}}}
}
除了if自己可以进行嵌套使用之外,其他流程控制语句同样可以嵌套使用,也可以与其他流程控制语句混合嵌套使用。这样,就可以灵活地使用if来进行各种条件判断了。
switch-case选择结构
语法格式
switch (expression) {case CONST1:// 语句块 Abreak;case CONST2:// 语句块 Bbreak;// ...default:// 默认语句块
}
expression 是要比较的值。必须是下述几种类型之一:byte,short,char,int,enum (jdk 5.0),String (jdk 7.0);
case 后跟编译时常量。表示一个分支。常量值必须是与表达式类型兼容的常量。所有case子句中的常量值互不相同;
break 可选,表示跳出整个 switch 语句,否则会出现“穿透”到下一个 case;
default 可选,处理没有匹配到任何 case 的情况。
执行过程
1、计算表达式的值。
2、从上到下依次比较各个 case 的常量值。
3、当匹配成功时,从该 case 开始执行。
4、如果没有遇到 break,程序会继续执行后续所有 case 的语句,直到遇到 break 或 switch 语句结束——这种现象叫**“case 穿透 (fall-through)”**。
5、如果所有 case 都不匹配,执行 default(如果存在)。
public class SwitchDemo {public static void main(String[] args) {int day = 3;switch (day) {case 1:System.out.println("Monday");break;case 2:System.out.println("Tuesday");break;case 3:System.out.println("Wednesday");break;case 4:System.out.println("Thursday");break;case 5:System.out.println("Friday");break;default:System.out.println("Weekend");}}
}
// Wednesday
int num = 2;
switch (num) {case 1:System.out.println("A");case 2:System.out.println("B");case 3:System.out.println("C");default:System.out.println("D");
}/*
B
C
D
*/
if-else与switch-case比较
if-else 语句
- 判断条件可以是任意 布尔表达式(boolean 值、关系表达式、逻辑运算等)。
 - 适合处理 范围判断 或 复杂逻辑。
 
switch-case 语句
- 适合处理 固定枚举值 的情况(例如整数、字符串、枚举类型)。
 - 多分支时更快(编译器优化成跳转表)
 - 可利用穿透性执行多个分支
 
(Java 14) switch表达式
switch 不仅可以作为语句使用,还可以作为一个返回值的表达式使用。
语法变化:
- 可以使用 
->箭头语法; - 可以直接返回值;
 - 支持多标签(多个 case 用逗号分隔);
 - 不再需要显式 
break,自动结束; - 可用 
yield返回值(复杂场景)。之后不能有代码了,Unreachable statement。 switch表达式的返回类型由所有分支的结果共同推断。所有分支必须返回同类型的值(或可兼容的类型)。- 表达式要求必须涵盖所有的可能,如果遗漏某些分支且没有 
default,编译器可能会报错。 - 不能混用旧语法的 
:和新语法的->。 
String dayName = switch (day) {case 1 -> "Monday";case 2 -> "Tuesday";case 3, 4, 5 -> "Midweek"; // 多个 case 合并case 6, 7 -> "Weekend";default -> {System.out.println("Invalid day");yield "Unknown"; // 块形式要用 yield 返回值}
};
Java 17 起,switch 表达式支持显式处理 null,如果没有专门处理 null,传入 null 会抛出 NullPointerException。
String result = switch (obj) {case null -> "Object is null";case String s -> "It's a String: " + s;default -> "Other type";
};
这里不需要 default,因为编译器知道 Day 枚举的所有值。
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }String typeOfDay = switch (day) {case SAT, SUN -> "Weekend";case MON, TUE, WED, THU, FRI -> "Weekday";
};
循环结构
循环(Loop)用于重复执行一段代码,直到满足某种条件为止。Java 提供三种基本循环语句:
for循环while循环do...while循环
🔁for
基本语法:
for (初始化表达式; 条件表达式; 迭代表达式) {循环体;
}
执行顺序:
- 执行一次初始化;
 - 判断条件 → 如果为 true,执行循环体;
 - 执行迭代表达式;
 - 重复 2~3;
 - 当条件为 false 时,退出循环。
 
for (int i = 0; i < 5; i++) {System.out.println("i = " + i);
}
/*
i = 0
i = 1
i = 2
i = 3
i = 4
*/
for 的三个部分(初始化、条件、迭代)都可以省略,但分号不能省略:
int i = 0;
for ( ; i < 5; ) {   // 省略初始化和迭代System.out.println(i);i++;
}
for (;;) {System.out.println("无限循环");
}
嵌套
for (int i = 1; i <= 3; i++) {for (int j = 1; j <= 2; j++) {System.out.println("i=" + i + ", j=" + j);}
}
🔁while
基本语法:
while (条件表达式) {循环体;
}
执行流程:
先判断条件 → 条件为真则执行循环体 → 再判断 → 重复,直到条件为假。
int i = 0;
while (i < 5) {System.out.println(i);i++;
}
while (true) { ... }
🔁do-while
基本语法:
do {循环体;
} while (条件表达式);
特点:
- 先执行一次循环体,再判断条件。
 - 不论条件是否为真,循环体至少执行一次。
 
int i = 0;
do {System.out.println(i);i++;
} while (i < 5);
break 与 continue
| 关键字 | 作用 | 
|---|---|
break | 立即终止整个循环,跳出循环体 | 
continue | 跳过本次循环,直接进入下一次循环判断 | 
for (int i = 0; i < 5; i++) {if (i == 3) break;      // 当 i==3 时跳出整个循环if (i == 1) continue;   // 跳过 i==1System.out.println(i);
}/*
0
2
*/
就近原则:
当一个循环中嵌套了多个循环时,break 或 continue 默认只会作用于离它最近的一层循环。
public class BreakDemo {public static void main(String[] args) {for (int i = 1; i <= 3; i++) { // 外层循环for (int j = 1; j <= 3; j++) { // 内层循环if (j == 2) {break; // 只跳出内层循环}System.out.println("i=" + i + ", j=" + j);}}}
}/*
i=1, j=1
i=2, j=1
i=3, j=1
*/
public class ContinueDemo {public static void main(String[] args) {for (int i = 1; i <= 3; i++) { // 外层循环for (int j = 1; j <= 3; j++) { // 内层循环if (j == 2) {continue; // 只跳过内层本次循环}System.out.println("i=" + i + ", j=" + j);}}}
}/*
i=1, j=1
i=1, j=3
i=2, j=1
i=2, j=3
i=3, j=1
i=3, j=3
*/
标签
在 Java 中,标签(Label) 其实就是给某个循环语句起一个名字,用于配合 break 或 continue 灵活控制多层嵌套循环的流程。
outer:  // 标签名
for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (j == 1) break outer;   // 跳出外层循环System.out.println("i=" + i + ", j=" + j);}
}// i=0, j=0
outer:
for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (j == 1) continue outer; // 直接进入 outer 的下一次循环System.out.println("i=" + i + ", j=" + j);}
}/*
i=0, j=0
i=1, j=0
i=2, j=0
*/
for 与 while 对比
| 对比项 | for 循环 | while 循环 | 
|---|---|---|
| 适用场景 | 知道循环次数 | 不确定循环次数 | 
| 结构 | 语法紧凑,变量通常在循环内部定义 | 条件判断分离,适合逻辑控制 | 
| 初始化位置 | 在循环头中 | 在循环外定义 | 
| 可读性 | 一目了然(适合计数型循环) | 更灵活(适合条件型循环) | 
| 无限循环 | for(;;) | while(true) | 
