[英]Java - How to properly handle a try catch block
我想知道什么是处理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);
还是这是不好的做法?
异常处理不是做出粗鲁假设的地方; 通常,在执行这部分代码时,是因为发生了意外的情况,这时您要非常小心地准确地检测和记录发生的事情,以便知道需要解决的问题。
将Exception作为捕获的异常类型的选择范围太广。 您正在调用的方法由于明显不同的原因而引发3个不同的异常。 只有其中一项是应该在这里捕获的。 同样,诸如NullPointerException之类的未经检查的异常也会被此捕获。 如果要在此catch块中添加一些代码,而无意中引入了NPE,则很难弄清楚出了什么问题。 过度捕获可能导致找不到错误或未正确处理错误。
(顺便说一句,Bakto Makoto很好地指出,无论如何,nextInt都不是您应该在这里所说的。)
在确定异常含义的狭义情况下(例如,如果在Makoto的示例代码中捕获了InputMismatchException或NumberFormatException),不记录异常是可以接受的。 但是结合捕获Exception,它可以隐藏错误并引起混乱。
您可能选择捕获Exception是因为处理大量不同的已检查异常,这些异常似乎无论如何都不会发生,似乎令人无法忍受。 通过为您不知道如何处理的异常提供合理的默认情况,提供一致的处理和记录异常的方式将有所帮助。 这样,如果您看到无法处理的异常,则始终可以选择引发该异常(可能是捕获该异常并将其包装在未经检查的异常中),知道如果引发该异常将被记录并结束程序。
对于很小的命令行程序,有时完全可以将无法处理的异常从main中抛出(通过将throws Exception添加到main方法中)。 可以用于玩具示例,小型学校项目等; 如果有计划记录输出(例如将stderr重定向到文件的批处理文件),则仅在生产代码中使用它:
public static void main(String... args) throws Exception {
... application code
}
在大多数情况下,所有主要方法代码都应放置在try块中,在其中捕获并记录任何Throwable:
public static void main(String... args) {
try {
... application code here
}
catch (Throwable t) {
logger.log(t);
}
}
两种选择都可以使您减少不适当地吞咽不便的检查异常的诱因。
简单的答案:你写的很好
更长的答案:try-catch块用于执行可能引发异常的代码,然后在发生异常时对其进行处理。 通常,catch块应具有处理异常的代码,但是您需要对其进行处理。 如果您当前拥有的语句是您希望如何响应异常,那么按惯例就可以了。 在catch块中要做的一些常见事情是:
printStacktrace
但是任何符合您的异常处理需求的方法都可以
实际上,此代码不会按您预期的方式起作用。 造成这种情况的主要原因有两个:
nextInt()
阻塞直到接收到整数; 也就是说,在读取整数之前,它不会关心您提供的输入,并且 userNth
和piDecimals
,也可能未定义其中一个或两个变量,从而阻止了编译。 另外, 不要捕获Exception
。 捕获异常时,请尽可能具体,因为Exception
还包括一些漂亮而危险的RuntimeException
例如NullPointerException
。
您要做什么:
userNth < 1 || userNth > piDecimals
时继续执行此userNth < 1 || userNth > piDecimals
userNth < 1 || userNth > piDecimals
。 为此,我们应该通过首先将输入解析为字符串, 然后解析为Integer
抛出正确的异常:
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;
}
另一部分是,如果userNth > 1 && userNth < piDecimals
,则必须决定显示什么消息,因为try...catch
不会覆盖该内容。 这,我留给读者练习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.