我想知道处理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);
或者这是不好的做法?
答案 0 :(得分:2)
异常处理不是做出草率假设的地方;通常在你执行这部分代码的时候,这是因为发生了一些意料之外的事情,这时你需要非常小心地准确地检测和记录发生的事情,这样你才能知道需要解决的问题。
选择Exception作为被捕获的异常类型过于宽泛。您正在调用的方法会因为截然不同的原因而抛出3个不同的异常;其中只有一个是应该在这里捕获的东西。此外,NullPointerException等未经检查的异常也会被捕获。如果你要在这个无意中引入NPE的catch块中添加一些代码,那么就很难弄清楚出了什么问题。您的过度捕获可能导致无法找到错误或错误无法正确处理。
(Btw Makoto说得好,无论如何,nextInt不是你应该在这里打电话的。)
在您确定异常意味着什么的狭窄情况下(例如,如果您在Makoto的示例代码中捕获了InputMismatchException或NumberFormatException),不能记录异常是可以接受的。但结合捕获异常,它有能力隐藏错误并引起混淆。
你可能选择捕捉异常,因为处理一堆不同的已检查异常,其中大部分似乎不太可能发生,似乎是一种无法容忍的麻烦。通过为不知道如何处理的异常提供合理的默认情况,提供一致的处理和记录异常的方法将有所帮助。这样,如果你看到一个你无法处理的异常,你总是可以选择让它被抛出(可能会捕获它并将其包装在未经检查的异常中),知道如果抛出它将被记录并结束你的程序。
对于一个非常小的命令行程序,有时完全可以让你无法处理的异常从main抛出(通过向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);
}
}
任何一种替代方案都会让你不恰当地吞下不方便的检查异常。
答案 1 :(得分:1)
简单回答:你写的很好
更长的答案:try-catch块用于执行可能抛出异常的代码,然后处理所述异常(如果发生)。通常,catch块应该具有处理异常的代码,但是您需要处理它。如果您当前拥有的陈述是您希望如何回应异常,那么按照惯例它就没问题了。 catch块中常见的一些事情是:
printStacktrace
但是任何符合你的异常处理需求的东西都很好
答案 2 :(得分:1)
实际上,这段代码不会按照你想要的方式运行。这有两个关键原因:
nextInt()
阻塞,直到收到整数;也就是说,在读取整数之前,它不会关心你给它的输入,并且userNth
和piDecimals
的方式,可能无法定义其中一个或两个变量,从而阻止了编译。此外,不会抓住Exception
。在捕获异常时尽可能具体,因为Exception
还包含一些漂亮而危险的RuntimeException
像NullPointerException
一样。
您要做的事情:
userNth < 1 || userNth > piDecimals
。为此,我们应该通过将输入解析为字符串 first ,然后作为{{}来获取正确的异常。 1}}:
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
并未涵盖此消息。这,我作为练习留给读者。