java编译器说这个异常永远不会在相应的try语句的主体中抛出 - 但是它被抛出了_is_

rou*_*ble 16 java exception-handling exception javac try-catch

我有以下代码:

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

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

Caught Exception in login(): HTTP transport error: java.net.UnknownHostException: abc
Run Code Online (Sandbox Code Playgroud)

这是正确和预期的.我重新编写代码以专门捕获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());
}
Run Code Online (Sandbox Code Playgroud)

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

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

这显然是错误的,因为抛出了异常,因为我之前已经抓住了它.我在这里错过了什么?

tia,卢布

Bal*_*usC 16

它不是扔了UnknownHostException.它只是出现在您实际捕获的异常消息中.这可能是您捕获的异常的根本原因.

要确定实际的异常,您应该打印更多细节.例如

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

或者只使用Throwable#toString()已包含异常类型和消息的内容:

} catch (Exception e) {
    logger.error("Caught Exception in login(): " + e);
}
Run Code Online (Sandbox Code Playgroud)

或者只是将Exception作为第二个logger参数传递,如果配置得当,它的stacktrace将被打印:

} catch (Exception e) {
    logger.error("Caught Exception in login(): " + e.getMessage(), e);
}
Run Code Online (Sandbox Code Playgroud)

根据您的意见更新:您最好的选择是更新捕获如下:

} catch (ClientTransportException e) {
    if (e.getCause() instanceof UnknownHostException) {
        // UHE.
    } else {
        // Other.
    }
}
Run Code Online (Sandbox Code Playgroud)

您绝对不应该根据消息进行区分.这是可携带性问题的原因.该消息是变化的敏感主题,甚至可能依赖于语言环境!