(Java)尝试捕获特定的代码行与尝试捕获整个函数

时间:2016-02-14 22:13:50

标签: java exception exception-handling try-catch

所以我正在使用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
        }
    }
}

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块。