do-while比while多执行一次,因其条件判断在循环体执行之后;适用用户输入校验等需先执行再判断场景,不适用遍历集合等常规循环;java中末尾分号不可省略,死循环主因是循环体内未更新条件变量。

do-while 为什么比 while 多执行一次?
因为它的条件判断在循环体执行之后,不是之前。只要第一次进入循环体,就必然执行至少一遍——哪怕 while 后面的表达式一开始就是 false。
常见错误现象:while (false) { ... } 一次都不跑,但 do { ... } while (false); 会跑一次。很多人写完发现逻辑多走了一次,回头翻代码才意识到自己误用了 do-while。
- 适用场景:用户输入校验(先读一次,再判断是否合法)、初始化后需立即检查的状态轮询、协议握手流程中“发请求→等响应→再判重试”这类固定首步动作
- 不适用场景:遍历集合、计数器递增类常规循环——用
for或while更直观,也更不容易出错 - 注意:Java 中分号不能省略,
do { ... } while (condition)少了末尾分号会编译报错illegal start of expression
如何避免 do-while 的死循环陷阱?
死循环往往不是因为条件写错,而是因为循环体内没更新判断变量,或者更新逻辑被 break/continue 意外跳过。
典型例子:读取用户输入直到输入数字,但忘了在 try-catch 外更新 input 变量:
立即学习“Java免费学习笔记(深入)”;
String input = "";
do {
input = scanner.nextLine();
try {
Integer.parseInt(input);
break;
} catch (NumberFormatException e) {
System.out.println("请输入数字");
// 忘了重新读 input?那这里就会卡死
}
} while (!input.matches("\d+"));
- 务必确认循环体内有且仅有**一条路径**能修改
while条件中的变量 - 如果用了
break提前退出,要检查它是否绕过了变量更新逻辑 - 调试时可在循环末尾加
System.out.println("loop end, condition is: " + condition);快速验证变量变化
do-while 在 Java 8+ Stream 场景下还值得用吗?
基本不值得。Stream 是声明式、不可变的,而 do-while 是命令式、依赖状态变更的。两者思维模型冲突,硬凑反而增加理解成本和出错概率。
比如想“尝试从数据库查数据,查不到就重试最多 3 次”,有人会写:
int attempt = 0;
Result result = null;
do {
result = db.query(id);
attempt++;
} while (result == null && attempt < 3);
这没问题,但换成 Stream 就很别扭——你没法把“重试”自然地映射成 map 或 filter。
- 真正适合 Stream 的是:已知数据源、一次性处理、无副作用操作
- 涉及状态、等待、重试、交互反馈的逻辑,
do-while(或封装成带状态的工具方法)反而更直接 - 性能上无差异,但可读性差很多:强行用
Stream.iterate模拟重试,代码会变得晦涩且难以调试
嵌套 do-while 时 label 跳转容易被忽略的细节
Java 支持用 label 配合 break 从多层循环中跳出,但 do-while 的 label 必须紧贴 do 关键字,不能放在大括号外或换行后。
错误写法:outer: { do { ... } while(...); } —— 这里 outer: 标记的是代码块,不是循环,break outer; 会编译失败。
- 正确写法:
outer: do { ... break outer; ... } while(...); - label 名称不能和变量名重复,否则编译报错
duplicate label - IDE(如 IntelliJ)对
do-while的 label 提示支持较弱,容易写错还不报红,建议优先用提取方法代替深层嵌套
最常被忽略的一点:do-while 的语义重心不在“循环次数”,而在“保证至少一次”。一旦你开始纠结“第几次执行”,说明逻辑可能更适合拆成初始化 + while 循环,而不是硬撑一个 do-while 结构。









