为什么catch块是可选的?

cod*_*Man 2 java exception-handling exception try-catch try-catch-finally

我有以下代码

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

    }
}
Run Code Online (Sandbox Code Playgroud)

这给出了错误

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Unhandled exception type CustomException
Run Code Online (Sandbox Code Playgroud)

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


从finally()的角度来看,我理解这一点

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

finally子句确保finally块在try块和任何可能执行的catch块之后执行,无论控制如何离开try块或catch块.


编辑:

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

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

T.J*_*der 10

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

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

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

    }
}
Run Code Online (Sandbox Code Playgroud)

try/finally没有catch是为了确保你清理你需要清理的任何东西,即使你自己没有处理这个例外.(确保不允许从内部抛出任何其他异常finally,否则您将隐藏主要异常.)

这是一个可以玩的例子(实时拷贝):

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");
}
Run Code Online (Sandbox Code Playgroud)

输出:

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

正如你所看到的,finally块的代码运行,无论是否发生了异常,但代码try/finally没有.


你的后续跟进询问为什么returnfinally错误中添加错误消失了:

try
{
    throw new CustomException();
}
finally
{
    return; // <=== Makes the compiler happy (but don't do it!)
}
Run Code Online (Sandbox Code Playgroud)

有趣的边缘案例!这是因为finally块中的代码总是运行,所以你总是返回而不是抛出,隐藏发生的异常.例如,这是序列:

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

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

这掩盖了异常发生的事实; 实际上,你已经通过finally块"处理"了异常(没有实际处理它).一般来说,这不是一个好主意; 用于catch处理异常,或在方法上声明它们,因此调用代码可以处理它们.