這個問題在這里已經有了答案: 即使在 Catch 中使用 NextLine 時,來自掃描儀的用戶輸入也會導致 try/catch 塊中的無限回圈 3 個答案 java.util.NoSuchElementException - 掃描儀讀取用戶輸入 4 個答案 Java 使用帶有 try-with-resources 的掃描儀 3 個答案 35 分鐘前關閉。
我最近開始學習 Java,遇到了一個我不理解的行為。
我有一個函式“methodOne”。如果我從主函式呼叫它,它作業正常。但是,如果我從同一個類中的另一個函式中呼叫它(在這種情況下將放在主函式中),我最終會陷入 me??thodOne 的無限回圈。我在這里缺少什么部分?
public class TestClass (){
int state;
boolean alive;
public void TestClass(){}
public void Init(){
alive=true;
while (alive) {
state = 0;
if (state == 0) {
state = methodOne();
} else if (state == 1) {
otherstatestuff;
} else if (state == 2) {
otherstatestuff;
} else if (state == 3) {
otherstatestuff;
} else if (state == 5) {
alive=false;
}
}
}
public int methodOne() {
try (java.util.Scanner scanner = new java.util.Scanner(System.in)) {
boolean runner = true;
while (runner) {
try{
System.out.println("Please provide your first name.");
String userInputFirstName = scanner.next();
System.out.println("Please provide your last name.");
String userInputLastName = scanner.next();
System.out.println(userInputFirstName " " userInputLastName);
state=5;
runner=false;
} catch (Exception ex){
System.out.println("Invalid Input!!!");
}
}
}
return state;
}
}
uj5u.com熱心網友回復:
您正在關閉掃描儀。不要那樣做。您的 linter 工具可能會在掃描儀上告訴您:哦,不!一個資源!你必須關閉它!
你的 linter 是錯誤的。不要關閉它。
禪宗第一課:Linter 是工具。工具可能是錯誤的。
禪宗第二課:在忽略例外之前思考 18 次。您在這里忽略了一個例外-您完全捕獲任何例外,然后獲取該例外中的所有無數資訊(這是 6 件事:例外型別、例外訊息、因果鏈、堆疊跟蹤、抑制的例外和特定子型別提供的任何詳細資訊,例如 SQLException 通過 .getSQLState()) 為您提供 DB 錯誤代碼 - 并將其全部扔進垃圾箱。現在你在問問題,因為你很困惑。難怪 - 你需要弄清楚的關鍵資訊被忽略了。
您得到的例外是:您無法呼叫.nextInt()掃描儀,因為您的掃描儀正在讀取已關閉System.in的,因此無法再次讀取。一旦可靠地立即拋出,我相信您可以看到您的代碼將永遠回圈。.nextInt()
解決方案
以下是正確使用掃描儀的方法:
- 制作一臺掃描儀,一次,一次。將其放入
main,并將掃描儀物件本身傳遞給任何想要使用它的方法。不要關閉它 - 任何地方。 - 制作掃描儀后立即呼叫
.useDelimiter("\\R"),使其行為符合您的預期(即:用戶在完成某些輸入后按回車鍵)。.nextX()然后,根據您的需要呼叫任何方法。
好像:
public static void main(String[] args) throws Exception {
Scanner s = new Scanner(System.in);
s.useDelimiter("\\R");
new TestClass(s).init();
}
public class TestClass {
private final Scanner s;
public TestClass(Scanner s) {
this.s = s;
}
....
}
注意:您粘貼的 TestClass 有一個錯字:您創建了一個名為TestClass. 你想洗掉void那里,然后你有一個建構式。而且你永遠不需要一個完全空白的建構式,只需省略那些 - 在這種情況下,你最終需要一個建構式,因為你需要一個來接收掃描儀。
uj5u.com熱心網友回復:
Init 包含一個無限回圈:
public void Init(){
alive=true;
while (alive) {
state = 0;
這將永遠運行。由于 alive 始終為 true 且 state 始終重置為 0,因此您始終呼叫 methodOne。Init 中的問題,而不是 methodOne。
uj5u.com熱心網友回復:
您需要通過在 catch 塊中呼叫scanner.nextLine() 來消耗換行符。
java.util.Scanner s = new java.util.Scanner(System.in);
while(true){
try {
int n = s.nextInt();
break;
}catch(Exception e){
System.out.println("Invalid Input!!!");
s.nextLine(); // <== insert this
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/410309.html
標籤:
