Java程序调用getSideLength方法后陷入循环异常求助
问题分析与解决方案
问题根源
你遇到的死循环问题,核心原因是重复创建并关闭Scanner实例导致标准输入流System.in被关闭:
- 在
getSideLength方法中,每次调用都会新建Scanner entry = new Scanner(System.in),读取完成后调用entry.close()。 - 关闭Scanner时会连带关闭底层的
System.in输入流,而输入流一旦关闭就无法重新打开。 - 回到main方法后,原有的
inputScanner已经无法读取任何内容,input.nextLine()会直接返回空字符串,触发"Please enter A, B, or C."的提示,陷入循环。
解决方案
只需要保证整个程序中只使用一个Scanner实例,并且仅在程序结束时关闭它。下面是修改后的完整代码:
package week7; import java.util.Scanner; import java.lang.Math; public class Lab7b { static void calculateSideA(Scanner input){ double b = getSideLength("B", input); double c = getSideLength("C", input); double a = Math.sqrt(Math.pow(c,2)-Math.pow(b,2)); System.out.println("A right triangle with sides 'B' = "+b+" and 'C' (hypotenuse) = "+c+", has a side 'A' which has a length of: "+a); } static void calculateSideB(Scanner input){ double a = getSideLength("A", input); double c = getSideLength("C", input); double b = Math.sqrt(Math.pow(c,2)-Math.pow(a,2)); System.out.println("A right triangle with sides 'A' = "+a+" and 'C' (hypotenuse) = "+c+", has a side 'B' which has a length of: "+b); } static void calculateSideC(Scanner input){ double a = getSideLength("A", input); double b = getSideLength("B", input); double c = Math.sqrt(Math.pow(a,2)+Math.pow(b,2)); System.out.println("A right triangle with sides 'A' = "+a+" and 'B' = "+b+", has a side 'C' (hypotenuse) which has a length of: "+c); } static double getSideLength(String letter, Scanner input){ boolean valid = false; double sideLength = 0; do{ try{ System.out.print("Please enter the length of the "+letter+" side: "); sideLength = input.nextDouble(); input.nextLine(); // 清除输入缓冲区的换行符 valid = true; }catch(Exception e){ System.out.println("Please enter a number."); valid = false; input.nextLine(); // 清除无效输入的剩余内容 } }while(!valid); // 不再关闭Scanner,统一在main方法结束时关闭 return sideLength; } public static void main(String[] args) { Scanner input = new Scanner(System.in); boolean rerun = false; boolean valid = false; do{ String letter = ""; do{ try{ System.out.print("Enter the side of the triangle would you like to calculate: (A/B/C) "); letter = input.nextLine(); if(letter.equalsIgnoreCase("A")||letter.equalsIgnoreCase("B")||letter.equalsIgnoreCase("C")){ valid = true; if(letter.equalsIgnoreCase("A")){ calculateSideA(input); } else if(letter.equalsIgnoreCase("B")){ calculateSideB(input); } else if(letter.equalsIgnoreCase("C")){ calculateSideC(input); } else{ System.out.println("Something has gone wrong."); } } else{ System.out.println("Please enter A, B, or C."); valid = false; } }catch(Exception e){ System.out.println("Please enter A, B, or C."); valid = false; } }while(!valid); valid = false; do{ System.out.print("Would you like to play again? (Y/N) "); String answer = input.nextLine(); if(answer.equalsIgnoreCase("Y")||answer.equalsIgnoreCase("N")){ if(answer.equalsIgnoreCase("Y")){ valid = true; rerun = true; } else{ System.out.println("Thank you. Come Again."); rerun = false; valid = true; } } else{ System.out.println("Please enter either Y or N"); valid = false; } }while(!valid); }while(rerun); input.close(); // 仅在程序结束时关闭一次Scanner } }
额外优化建议
- 添加边长合法性检查:比如边长必须大于0,计算直角边时斜边长度必须大于已知直角边,避免出现平方根负数的异常。
- 格式化输出结果:使用
String.format保留两位小数,让输出更美观,例如String.format("%.2f", a)。
内容的提问来源于stack exchange,提问作者Ammon
相关产品推荐
相关产品推荐

