Java-如何正确处理try-catch块

Java-如何正确处理try-catch块,java,try-catch,Java,Try Catch,我想知道处理try/catch块的正确约定是什么。很明显,try块中应该包含什么,但是catch块呢 我是否可以像下面这样向用户发送消息: do { try { System.out.println("Pi to the number of decimal places:"); Scanner in = new Scanner(System.in); userNt

我想知道处理try/catch块的正确约定是什么。很明显,
try
块中应该包含什么,但是
catch
块呢

我是否可以像下面这样向用户发送消息:

       do {
            try {
                System.out.println("Pi to the number of decimal places:");
                Scanner in = new Scanner(System.in);
                userNth = in.nextInt();
            } catch (Exception e) {
                System.out.println("Error: Enter a number between 1 and 100");
            }
        } while(userNth < 1 || userNth > piDecimals);
do{
试一试{
System.out.println(“Pi到小数位数:”);
扫描仪输入=新扫描仪(系统输入);
userNth=in.nextInt();
}捕获(例外e){
System.out.println(“错误:输入一个介于1和100之间的数字”);
}
}而(userNth<1 | | userNth>piDecimals);

还是这种做法不好?

简单的回答:你写的很好

更详细的回答:try-catch块用于执行可能引发异常的代码,然后在异常发生时处理该异常。通常,catch块应该有处理异常的代码,但是您需要处理它。如果您当前拥有的语句是您希望如何响应异常的,那么按照惯例就可以了。在catch块中要执行的一些常见操作包括:

  • 抛出另一个封装抛出异常的异常。(我在解析时经常这样做,这样就可以有一个ParseException)
  • 抛出一个封装抛出异常的运行时异常,并让java的默认未捕获异常处理程序处理它。(我在编写快速临时程序时经常这样做,我不想处理选中的异常)
  • 将其传递给程序中的一些通用处理程序,例如显示错误的GUI等
  • 对其调用
    printStacktrace

但是任何适合您异常处理需要的东西都可以

简单的回答:您写的很好

更详细的回答:try-catch块用于执行可能引发异常的代码,然后在异常发生时处理该异常。通常,catch块应该有处理异常的代码,但是您需要处理它。如果您当前拥有的语句是您希望如何响应异常的,那么按照惯例就可以了。在catch块中要执行的一些常见操作包括:

  • 抛出另一个封装抛出异常的异常。(我在解析时经常这样做,这样就可以有一个ParseException)
  • 抛出一个封装抛出异常的运行时异常,并让java的默认未捕获异常处理程序处理它。(我在编写快速临时程序时经常这样做,我不想处理选中的异常)
  • 将其传递给程序中的一些通用处理程序,例如显示错误的GUI等
  • 对其调用
    printStacktrace

但是,任何符合您的异常处理需求的东西都可以

异常处理并不是做出轻率假设的地方;通常,当代码的这一部分被执行时,这是因为发生了意想不到的事情,这时您需要非常小心地准确地检测和记录所发生的事情,以便能够知道需要修复的内容

选择异常作为捕获的异常类型太广泛了。您调用的方法抛出3个不同的异常,原因截然不同;其中只有一个应该在这里抓到。此外,未经检查的异常(如NullPointerException)也会被此捕获。如果您要向这个catch块添加一些代码,这些代码无意中引入了一个NPE,那么很难找出哪里出了问题。您的越轨捕获可能导致找不到bug或错误得不到正确处理

(顺便说一句,Makoto提出了一个很好的观点,即nextInt无论如何都不是您应该在这里使用的名称。)

如果您确定异常的含义(例如,如果您在Makoto的示例代码中捕获到InputMismatchException或NumberFormatException),则不记录异常是可以接受的。但与捕获异常相结合,它有能力隐藏错误并造成混乱

您可能选择捕获异常,因为处理一系列不同的已检查异常(其中大多数似乎无论如何都不可能发生)似乎是一件令人无法忍受的麻烦事。通过为您不知道如何处理的异常提供合理的默认情况,提供一致的处理和记录异常的方法将有所帮助。这样,如果您看到无法处理的异常,您总是可以选择让它被抛出(可能捕获它并将其包装在未检查的异常中),知道如果抛出它将被记录并结束您的程序

对于一个非常小的命令行程序,有时完全可以让无法处理的异常从main抛出(通过向main方法添加throwsexception)。这对于玩具示例、小型学校项目等来说是可以的。;如果有记录输出的计划(比如将stderr重定向到一个文件的批处理文件),我只会在生产代码中使用它:

在大多数情况下,所有主要方法代码都应放在一个try块中,在该块中捕获并记录任何可丢弃的内容:

public static void main(String... args) {
    try {
        ... application code here
    }
    catch (Throwable t) {
        logger.log(t);
    }
}

任何一种选择都会降低您不适当地接受不方便的检查异常的诱惑力。

异常处理不是做出轻率假设的地方;通常,当代码的这一部分被执行时,这是因为发生了意想不到的事情,这时您需要非常小心地准确地检测和记录所发生的事情,以便能够知道需要修复的内容

选择异常作为捕获的异常类型太广泛了。您调用的方法抛出3个不同的异常,原因截然不同;其中只有一个应该在这里抓到。此外,未经检查的异常(如NullPointerException)也会被此捕获。如果你想给它添加一些代码
public static void main(String... args) {
    try {
        ... application code here
    }
    catch (Throwable t) {
        logger.log(t);
    }
}
try {
    System.out.println("Pi to the number of decimal places:");
    userNth = Integer.parseInt(in.nextLine());
} catch (NumberFormatException e) {
    System.out.println("Error: Enter a number between 1 and 100");
    // You have to set this value to something so that userNth is defined!
    userNth = Integer.MAX_VALUE;
}