java编译器说这个异常永远不会在相应的try语句的正文中抛出 - 但它_is_抛出

我有以下代码:

try {
    //jaw-ws service port operation
    port.login();
} catch (Exception e) {
    logger.error("Caught Exception in login(): " + e.getMessage());
}

当上述内容使用不正确的主机名运行时,我得到:

Caught Exception in login(): HTTP transport error: java.net.UnknownHostException: abc

这是正确和预期的。我重写了代码以专门捕获UnknownHostException,如下所示:

import java.net.UnknownHostException;
try {
    //jaw-ws service port operation
    port.login();
} catch (UnknownHostException uhe) {
    //do something specific to unknown host exception
} catch (Exception e) {
    logger.error(Caught Exception in login(): " + e.getMessage());
}

但是,当我尝试编译它时,我得到:

[javac] foo.java: exception java.net.UnknownHostException is never thrown in body of corresponding try statement
[javac]         } catch (UnknownHostException uhe) {
[javac]                  ^

这显然是错误的,因为异常被抛出,正如我之前捕获的那样。我在这里错过了什么?

蒂亚,卢布


答案 1

它没有抛出.它只是出现在您实际捕获的异常的消息中。这可能是您捕获的异常的根本原因。UnknownHostException

若要确定实际的异常,应打印更多详细信息。例如:

} catch (Exception e) {
    logger.error("Caught Exception in login(): " + e.getClass().getName() + ": " + e.getMessage());
}

或者只是使用Thurlable#toString(),它已经包含异常类型和消息:

} catch (Exception e) {
    logger.error("Caught Exception in login(): " + e);
}

或者只是将异常作为第二个记录器参数传入,如果配置良好,则将打印其堆栈跟踪:

} catch (Exception e) {
    logger.error("Caught Exception in login(): " + e.getMessage(), e);
}

根据您的评论进行更新:您最好的办法是按如下方式更新捕获:

} catch (ClientTransportException e) {
    if (e.getCause() instanceof UnknownHostException) {
        // UHE.
    } else {
        // Other.
    }
}

您绝对不应该根据消息进行区分。这是便携性问题的隐患。该消息是更改的敏感主题,甚至可能依赖于区域设置!


答案 2

有各种微妙的(或在某些情况下不微妙的)方法可以在未显式声明的情况下引发已检查的异常。本页列出了一些


推荐