【问题标题】:How to create a proper custom exception class?如何创建适当的自定义异常类?
【发布时间】:2015-12-16 20:27:12
【问题描述】:

我正在尝试创建一个自定义异常类,但遇到了很多麻烦。有人可以帮我吗!我最近才开始编程,希望能得到一些指点。

import java.util.Random;
import java.util.Scanner;
import java.util.InputMismatchException;

public class GuessingGame {

    public static void main(String[]args) throws BadGuessException
    {
        int min = 1;
        int max = 10;
        Random rand = new Random();

        int numberToGuess = rand.nextInt((max - min) + 1) + min;    

        Scanner input = new Scanner(System.in);
        int guess;
        boolean win = false; 
        int numberOfTries = 0;

        while (!win) 
        {

            System.out.println("Guess a number between 1 and 10: ");
            try
            {
                guess = input.nextInt();
                numberOfTries++;


                if (guess == numberToGuess)
                {       
                    win = true;
                    System.out.println("YOU GOT IT!");
                    System.out.println("It took you " + numberOfTries + " tires.");

                }
                else
                {
                    throw new BadGuessException();
                }
            }
            catch(InputMismatchException e)
            {
                e.getMessage();
            }
        }
    }

}


    import java.util.*;

public class BadGuessException extends Exception {

    String message = "Sorry, that was an invalid guess!";

    //Default Constructor 
    public BadGuessException()
    {
        super();
    }

    //Parameterized Constructor
    public BadGuessException(Throwable cause)         
    {  
      super(cause);        
    }      

}

我应该创建 2 个构造函数,一个是默认的,一个是参数化的。如果用户输入 1-10 之间的数字,我应该在 catch 块中捕获它并打印消息“invalid guess”如果他们输入字母或其他内容,输出应该类似于“Invalid input”(我应该抓住BadGuessException 中的无效输入,然后将其传递给 InputMismmatch?如果是,我该怎么做?) 现在,当我运行这段代码时,如果我输入一个字母,它不会崩溃,但 while 循环会不断迭代,我无法再输入输入。它只是不断重复“猜一个 1-10 之间的数字”。

我假设这是因为一旦 try 块执行一次,它就不会再次执行?我该如何解决?很抱歉有任何混淆,很高兴澄清!任何帮助深表感谢。

另外,我不确定如何同时捕获 2 个不同的异常。一种用于无效猜测,一种用于无效输入。 :/

【问题讨论】:

  • 应该如何同时抛出两个异常?
  • 你快到了。只需在已经存在的catch 下方添加一个catch ( BadGuessException e ) { System.out.println( e.getMessage() ); }(另外:e.getMessage(); 本身没有任何作用,您需要打印它!)。 Idk 关于扫描仪,但也许你需要 input.next() 来获取(并丢弃)那封信。

标签: java oop exception-handling


【解决方案1】:

异常应该用于处理错误、无效输入、非法、异常情况。如果没有猜到正确的数字是错误的,那听起来就像不是读心术是错误的。所以BadGuessException在这里被误用了。

为了更好的用例,如何为无意义的输入抛出这个异常?例如,由于程序要求用户输入 1 到 10 之间的数字,因此输入 -3 或 99 显然是错误的。

中间的循环可以相应修正:

while (!win) {
    System.out.println("Guess a number between 1 and 10: ");
    try {
        guess = input.nextInt();
        numberOfTries++;

        if (guess == numberToGuess) {
            win = true;
            System.out.println("YOU GOT IT!");
            System.out.println("It took you " + numberOfTries + " tires.");
        } else if (guess < 1 || guess > 10) {
            throw new BadGuessException();
        }
    } catch (InputMismatchException e) {
        input.nextLine();
    }
}

至于创建自定义异常类,您已经这样做了。写的有点乱,清理一下(去掉不必要的东西)就变成了:

public class BadGuessException extends Exception {

    private static final String message = "Sorry, that was an invalid guess!";

    public BadGuessException() {
        super(message);
    }
}

更新

我修复了您代码中的另一个错误:如果您输入非整数输入,则会抛出 InputMismatchException。反复。永远。 这是因为如果输入无效,input.nextInt() 不会消耗输入。所以无效的输入会一直留在那里,input.nextInt() 会一直失败,让你的程序陷入无限循环。

要解决这个问题,您必须以某种方式消耗错误的输入,例如通过阅读以下行:

    } catch (InputMismatchException e) {
        input.nextLine();
    }

【讨论】:

  • 我也想创建一个参数化的构造函数。但是当我查看 Exception 的文档时,似乎可以有多个参数。我会使用哪些参数?只是一个 Throwable 类型?还是字符串?
  • 只使用您需要的,仅此而已。如果您不需要其他任何东西,请不要添加任何其他内容。在这个例子中,确实需要Throwable
  • 当我在打印语句中执行 e.getMessage 时,它​​说找不到符号
  • 所以当我捕捉到 InputMismatch 异常时,代码永远不会回到询问我输入的状态,它只是不断地重复“再次猜测”。 (我在 ControlAltDel 的回答中更详细地发布了评论。你能帮我澄清一下吗?
  • 哦,我明白了。我对此有一个修复和解释,请参阅我的更新答案。
【解决方案2】:

我认为你想要的是,如果他们做出猜测并且它不正确,那么你的循环应该再次运行,对吗?在这种情况下,您应该调整循环,如下所示。此外,在您捕获 InputMismatchException 的地方,您正在吞下异常而不打印或处理它:这是非常糟糕的做法。我也为你更新了这个。

while (!win) 
        {

            System.out.println("Guess a number between 1 and 10: ");
            try
            {
                guess = input.nextInt();
                numberOfTries++;

                win=true;

                if (guess == numberToGuess)
                {       
                    win = true;
                    System.out.println("YOU GOT IT!");
                    System.out.println("It took you " + numberOfTries + " tires.");

                }
                else
                {
                    throw new BadGuessException();
                }
            }
            catch(InputMismatchException e)
            {
                System.out.println("Please input a number betwee 1 and 10!");
            }
            catch(BadGuessException ex) {
                System.out.println("Sorry, you guessed the wrong number!");
            }
        }

【讨论】:

  • 您好,非常感谢您!捕获错误的输入,但是,当我输入一个字母时,它会不断重复。它不再要求我再次输入。 :/ (我删除了关于 if 语句的 win = true) 这个错误对我来说是一个愚蠢的错误。
  • 当我输入一个字母时,程序进入一个无限循环并不断显示以下消息,并且从不要求我输入“猜一个介于 1 和 10 之间的数字:请输入一个介于 1 和10个!” @ControlAltDel
【解决方案3】:

您永远不会捕获 BadGuessException,因此它将被抛出 while 循环并且程序将退出。如果要继续,必须在循环内捕获异常。

我同意 janos 的评论,即这不是很好地使用异常。猜错是正常游戏流程的一部分,不是吗?

但是为了练习,我会例如将循环内的所有逻辑拉到一个新的私有方法中,让它抛出这个异常,然后在循环中捕获它。您可以像这样连续捕获多个异常。

while (!win) {
    try {
        win = makeGuess();
    } catch (InputMismatchException e) {
            e.getMessage();
    }  catch (BadGuessException e) {
        System.out.println("Wrong guess");
    } 
}

private boolean makeGuess() throws BadGuessException, InputMismatchException {
   ...
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 2012-01-15
    相关资源
    最近更新 更多