You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java程序调用getSideLength方法后陷入循环异常求助

问题分析与解决方案

问题根源

你遇到的死循环问题,核心原因是重复创建并关闭Scanner实例导致标准输入流System.in被关闭:

  • 在getSideLength方法中,每次调用都会新建Scanner entry = new Scanner(System.in),读取完成后调用entry.close()。
  • 关闭Scanner时会连带关闭底层的System.in输入流,而输入流一旦关闭就无法重新打开。
  • 回到main方法后,原有的input Scanner已经无法读取任何内容,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:35:28