首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Scanner.hasNextInt() 導致無限循環的根因與三種解決方案

     編輯:Java 綜合教學

Scanner.hasNextInt() 導致無限循環的根因與三種解決方案

使用 Scanner 做輸入校驗時,若輸入非整數,hasNextInt() 返回 false,但緩衝區內的非法 token 未被消費,導致死循環反覆進入 else 分支。本文深度解析根因並提供三種解決方案。

問題復現代碼

Scanner sc = new Scanner(System.in);
while (true) {
    System.out.println("請輸入一個整數");
    if (sc.hasNextInt()) {
        int i = sc.nextInt();
        System.out.println(i);
    } else {
        System.out.println("輸入錯誤,請重新輸入");
        // 這裡缺少消費緩衝區非法 token 的操作!
    }
}

根因分析

  • hasNextInt() 只檢查下一個 token 是否為整數,不消費 token
  • 輸入 "abc" 時,token "abc" 留在緩衝區
  • 下次循環 hasNextInt() 仍檢查 "abc",返回 false
  • 陷入無限循環,控制台瘋狂輸出「輸入錯誤」

三種解決方案

方案一:循環內創建新 Scanner(不推薦,資源浪費)

while (true) {
    Scanner sc = new Scanner(System.in); // 每次新建
    if (sc.hasNextInt()) { ... }
    else { System.out.println("錯誤"); }
}

方案二:next() 消費單個 token(適用單詞輸入)

} else {
    String next = sc.next(); // 消費掉 "abc"
    System.out.println("您輸入的是:" + next + ",請重新輸入");
}

缺陷:輸入 "abc def 123" 會循環三次,分別消費 abc、def,最後處理 123。

方案三:nextLine() 消費整行(推薦,最徹底)

} else {
    String nextLine = sc.nextLine(); // 一次性消費整行 "abc def 123"
    System.out.println(nextLine);
}

優勢:無論輸入多少非法字符,一次性清空緩衝區至換行符,下次循環直接檢查新輸入。

緩衝區機制圖解

輸入: "22 aaa 333 ccc"
1. hasNextInt() -> true, nextInt() 消費 "22",緩衝區剩 "aaa 333 ccc"
2. hasNextInt() -> false, nextLine() 消費 "aaa 333 ccc",緩衝區空
3. 等待新輸入...

最佳實踐模板

Scanner sc = new Scanner(System.in);
while (true) {
    System.out.print("請輸入整數: ");
    if (sc.hasNextInt()) {
        int num = sc.nextInt();
        System.out.println("您輸入: " + num);
        break; // 或繼續業務邏輯
    } else {
        String garbage = sc.nextLine(); // 關鍵:消費整行非法輸入
        System.out.println("無效輸入: [" + garbage + "],請重試");
    }
}
sc.close();

核心心法

理解緩衝區,就明白了!
hasNextXxx() 只看不拿,nextXxx() 拿走 token,nextLine() 拿走整行。
異常分支必須消費掉非法數據,否則死循環必現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved