所以我正在使用Java开发一个小项目,而且我已经找到了主要方法,我不确定如何正确处理尝试捕获异常。
我应该是:
尝试捕获我知道的特定代码行可能会抛出异常? 喜欢:
public class Stuff {
public static void main(String[] args) {
try {
// code that will probably throw exception 1 or 2
} catch (exception1 e) {
// handle exception 1
} catch (exception2 e) {
// handle exception 2
}
//rest of code that probably won't throw any exceptions
}
}
OR
尝试捕获整个main方法,即使try块中的某些代码不会抛出异常?像:
public class Stuff {
public static void main(String[] args) {
try {
// code that will probably throw exception 1 or 2
// rest of code that probably won't throw any exceptions
} catch (exception1 e) {
// handle exception 1
} catch (exception2 e) {
// handle exception 2
}
}
}
答案 0 :(得分:3)
要考虑的一件事是,如果抛出异常,在catch
块之后运行的代码是否仍然有效。例如,请考虑以下方法:
private void readFile()
{
List<String> lines = null;
try
{
lines = Files.readAllLines(Paths.get("/to/my/file.txt"));
}
catch (IOException e)
{
// log exception...
}
for (String line : lines)
{
System.out.println(line);
}
}
如果readAllLines
抛出IOException
,那么catch块之后的代码将抛出NullPointerException
。
<小时/> 决定何时捕获vs重新抛出异常有一个更大的问题。我通过问自己这个问题来回答:
“如果抛出此异常,我的方法是否可以履行合同?”
是:处理异常并继续履行方法的合同
否:重新抛出异常(在throws
子句中或包装在更合适的异常类型中)。
例如,使用this method,
public static List<String> readAllLines(Path path) throws IOException
如果文件不存在,则无法返回文件行的列表,因此会抛出IOException
。
另一方面,this method
public static boolean deleteIfExists(Path path) throws IOException
如果文件不存在,不会抛出异常(而是返回boolean
来告诉你发生了什么)。考虑这种方法的合同的一种方法是,“在执行此方法之后,path
”处将没有文件。所以在这种情况下,如果文件不存在,合同仍然可以实现。
答案 1 :(得分:2)
这取决于 - 如果引发任何异常,是否应该执行非异常代码?这不是最佳实践&#34;问题,这是一个&#34;你的规格是什么?&#34;问题
假设您的代码如下所示:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
someValue = defaultValue;
}
// Continue, possibly using the default value
在这种情况下,您应该只包装单行。另一方面,也许您的代码如下所示:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
log.fatal("The universe is crashing! Run for your lives!");
System.exit();
}
// Continue, assuming that parsing succeeded
在这种情况下,它是一种风格选择。这两种方法都是有效的,尽管如此极端失败,例如在这个例子中,简单地声明方法抛出某些内容并完全忘记try / catch可能更好。事实上,无论你的处理代码是什么,如果你的方法在拯救之后唯一要做的事情,你应该考虑省略try / catch并改为使用throws
子句。
然而,第三种情况客观上是错误的:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
log.info("something strange happened");
// Don't bother the calling code with the exception, it can't handle it.
}
// Continue, assuming that parsing succeeded
在这种情况下,延续代码必须进入try
块。