为什么catch块是可选的?

时间:2015-03-04 14:26:34

标签: java exception exception-handling try-catch try-catch-finally

我有以下代码

public static void nocatch()
{
    try
    {
        throw new Exception();
    }
    finally
    {

    }
}

哪个给出了错误

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Unhandled exception type CustomException

我的问题是为什么设计的catch块是可选的,当没有办法绕过没有捕获时?


从最后()的角度来看,我理解

finally应至少有一个try块,catch是可选的。 finally块的重点是确保无论是否抛出异常,都会清理内容。根据{{​​3}}

  

finally子句确保finally块在try块之后执行,并且可以执行任何catch块,无论控制如何离开try块或catch块。


修改:

通过在f​​inally块中添加一个返回值,编译器不会给出错误为什么?!

public static void nocatch()
{
    try
    {
        throw new Exception();
    }
    finally
    {
        return; //By adding this statement, the compiler error goes away! Please let me know why
    }
}

1 个答案:

答案 0 :(得分:10)

  

我的问题是为什么设计的catch块是可选的,当没有办法绕过没有捕获时?

是的:声明该方法抛出异常:

public static void nocatch() throws CustomException
{
    try
    {
        throw new CustomException();
    }
    finally
    {

    }
}
没有try/finally

catch是为了确保您清理清理所需的任何内容,即使您没有自己处理异常。 (确保不允许在finally内抛出任何其他异常,否则您将隐藏主要异常。)

以下是使用(live copy)的示例:

private static class CustomException extends Exception {
}
public static void main (String[] args) throws java.lang.Exception
{
    try
    {
        System.out.println("Calling nocatch(false)");
        nocatch(false);
    }
    catch (CustomException ce) {
        System.out.println("Caught CustomException for false case");
    }
    try
    {
        System.out.println("Calling nocatch(true)");
        nocatch(true);
    }
    catch (CustomException ce) {
        System.out.println("Caught CustomException for true case");
    }
}

public static void nocatch(boolean foo) throws CustomException
{
    try
    {
        if (foo) {
            System.out.println("Throwing");
            throw new CustomException();
        }
    }
    finally
    {
        System.out.println("In finally");
    }
    System.out.println("Reached outside the try/finally block");
}

输出:

Calling nocatch(false)
In finally
Reached outside the try/finally block
Calling nocatch(true)
Throwing
In finally
Caught CustomException for true case

如您所见,无论是否发生异常,finally块的代码都会运行,但{/ 1>}之后的代码不会。


重新跟进,了解为什么在try/finally中添加return会导致错误消失:

finally

有趣的边缘案例!这是因为try { throw new CustomException(); } finally { return; // <=== Makes the compiler happy (but don't do it!) } 中的代码始终运行,因此您将始终返回而不是抛出,隐藏发生的异常。例如,这是序列:

  1. finally抛出异常,将控件转移到throw new CustomException()

  2. finally块中的代码从方法发出正常返回

  3. 这隐藏了异常发生的事实;实际上,您已经通过finally块“处理”了异常(没有实际处理它)。一般来说,这不是一个好主意;使用finally来处理异常,或者在方法上声明它们,这样调用代码就可以处理它们。