【问题标题】:try-catch statement not returning to try block when catching exception捕获异常时,try-catch 语句不返回到 try 块
【发布时间】:2014-03-16 17:55:36
【问题描述】:

我有一个写的方法。此方法仅扫描用户输入的整数输入。如果用户输入一个字符值,它将抛出一个输入不匹配异常,这在我的 Try-Catch 语句中处理。问题是,如果用户输入任何不是数字的内容,然后引发异常,我需要该方法循环返回以再次要求用户输入。据我了解,如果捕获到错误,Try catch 语句会自动循环回 Try 块。这不正确吗?请指教。

这是我的方法(很简单):

public static int getMask() {
        //Prompt user to enter integer mask
        Scanner keyboard = new Scanner(System.in);
        int output = 0;
        try{
            System.out.print("Enter the encryption mask: ");
            output = keyboard.nextInt();
        }
        catch(Exception e){
            System.out.println("Please enter a number, mask must be numeric");
        }
        return output;
    }//end of getMask method

以下是该方法在我的程序中的实现方式:

//get integer mask from user input
        int mask = getMask();
        System.out.println("TEMP mask Value is: " + mask);

/************ *************** ********/ 这是我更新的代码。它创建了一个我无法逃脱的无限循环。我不明白为什么我要为此苦苦挣扎。请帮忙。

public static int getMask() {
    //Prompt user to enter integer mask
    Scanner keyboard = new Scanner(System.in);
    int output = 0;
    boolean validInput = true;

    do{
    try {
        System.out.print("Enter the encryption mask: ");
        output = keyboard.nextInt();
        validInput = true;
    }
    catch(InputMismatchException e){
        System.out.println("Please enter a number, mask must be numeric");
        validInput = false;
        }
    }while(!(validInput));

    return output;

/************ ********/FINAL_ANSWER 我终于能够得到它。我想我只需要更多地研究布尔逻辑。有时它让我头晕目眩。使用整数测试实现循环效果很好。我想是我自己的用户错误。这是我的最终代码在更好的异常处理下正常工作。如果您有任何批评意见,请在 cmets 中告诉我。

//get integer mask from user input
        int repeat = 1;
        int mask = 0;
        do{
            try{

        mask = getMask();
        repeat = 1;
            }
            catch(InputMismatchException e){
                repeat = 0;
            }
        }while(repeat==0);

【问题讨论】:

  • The try block。不,它不会循环返回。
  • 谢谢我已经读过了,但我显然缺少一个核心概念
  • 那么我需要一个 do-while 循环。嗯,这是有道理的。我只是对 try-catch 块的工作方式感到困惑。谢谢。

标签: java try-catch


【解决方案1】:

据我了解,如果捕获到错误,Try catch 语句会自动循环回 Try 块。这不正确吗?

不,这是不正确的,我很好奇您是如何达成这种理解的。

您有几个选择。例如(这不会按原样工作,但让我们先讨论错误处理,然后阅读下文):

// Code for illustrative purposes but see comments on nextInt() below; this
// is not a working example as-is.
int output = 0;
while (true) {
    try{
        System.out.print("Enter the encryption mask: ");
        output = keyboard.nextInt();
        break;
    }
    catch(Exception e){
        System.out.println("Please enter a number, mask must be numeric");
    }
}

除其他外;您选择的选项通常取决于您的偏好(例如,fge's answer 是相同的想法,但略有不同),但在大多数情况下,这直接反映了您正在尝试做的事情:“继续询问,直到用户输入有效数字。”

还要注意,就像提到的 fge 一样,您通常应该捕获您准备处理的最严格的异常。 nextInt() 会引发一些不同的异常,但您的兴趣特别在于 InputMismatchException。你不准备处理,例如,IllegalStateException——更不用说如果抛出意外异常但你的程序假装它们只是与无效输入相关(因此永远不会通知你一个发生了不同的问题)。

现在,也就是说,Scanner.nextInt() 这里还有另一个问题,如果无法将令牌解析为整数,则令牌会留在流中。如果您不将该令牌从流中取出,这将使您陷入循环。为此,您实际上想要使用next()nextLine(),以便无论如何都会消耗令牌;然后你可以用Integer.parseInt()解析,例如:

int output = 0;
while (true) {
    try{
        System.out.print("Enter the encryption mask: ");
        String response = keyboard.next(); // or nextLine(), depending on requirements
        output = Integer.parseInt(response);
        break;
    }
    catch(NumberFormatException e){ // <- note specific exception type
        System.out.println("Please enter a number, mask must be numeric");
    }
}

请注意,这仍然直接反映了您想要做什么:“不断询问,直到用户输入有效数字,但无论他们输入什么都会消耗输入。”

【讨论】:

    【解决方案2】:

    据我了解,如果捕获到错误,Try catch 语句会自动循环回 Try 块。这不正确吗?

    确实不正确。 try 块只会被执行一次。

    您可以使用它来“解决”它(尽管JasonC's answer 更可靠——随它去吧):

    boolean validInput = false;
    
    while (!validInput) {
        try {
            System.out.print("Enter the encryption mask: ");
            output = keyboard.nextInt();
            validInput = true;
        }
        catch(Exception e) {
            keyboard.nextLine(); // swallow token!
            System.out.println("Please enter a number, mask must be numeric");
        }
    }
    return output;
    

    进一步说明:您不应该捕捉Exception,而是捕捉更具体的异常类。

    【讨论】:

    • 感谢您回复代码,非常感谢。除非我能直观地看到比较的正确答案,否则告诉我我做错了什么永远不会有帮助。如果允许,我会接受你的回答。
    • 哦,我也错过了一个问题; nextInt() 将在失败时将令牌留在流中。
    • 我的或@JasonC 的...但是请注意不要抓住Exception 的建议,如果你这样做真的会遇到意想不到的麻烦
    • @JasonC 那么如何吞下它呢? .next()catch 块中?
    • @fge 这是一种选择。另一个选项是.next(),无论如何然后Integer.parseInt()。再次归结为个人喜好。处理程序中 next() 的潜在并发症是 next() 也可能由于其他原因抛出 - 与这种情况(甚至是典型用法)无关,但需要注意。
    【解决方案3】:

    如 cmets 中所述,try-catch -blocks 不会循环。如果要循环,请使用 forwhile

    【讨论】:

    • 这是对第一个问题的一个很好的答案,但如果它提供了一个可行的替代方案会更有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 2015-06-21
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多