Java 异常抛出自省
Java Exception-throwing introspection
我有一个关于 Java 方法内省的问题,特别是关于异常的问题。假设我有以下代码:
private String getCustomReportResponse(HttpsURLConnection customReportConnection) {
int responseCode = 0;
try {
responseCode = customReportConnection.getResponseCode();
return httpResponseBodyExtractor.extractResponseBodyFrom(customReportConnection);
} catch (IOException e) {
translateIntoRelevantException(responseCode, e);
}
}
假设 try 块中的两个语句都能够抛出 IOException - 在这种情况下,将调用 translateIntoRelevantException
方法,如下所示:
private void translateIntoRelevantException(int responseCode, IOException e) {
if(is5xxResponseCode(responseCode)) {
throw new ServerResponseException("Could not generate report - returned response code " + responseCode, e);
}
throw new ReportException("GeminiReportException: Unable to parse response from HTTP body when requesting custom Gemini report.", e);
}
因此,无论发生什么情况,要么 returned 字符串,要么抛出异常。除了 getCustomReportResponse
方法不在 catch 块后添加 return 语句就无法编译,这是绝对无法访问的。事实上,如果我将 translateIntoRelevantException
的内容放入 catch 块中,它会编译,这对我来说似乎很愚蠢。
我应该补充一下,抛出的异常是运行时异常,但我也试过让它们成为检查异常,但问题仍然存在。
谁能解释一下为什么?
这是 "rethrow" 辅助方法所面对的 common problem。
编译器不知道(也没有办法表明)方法 translateIntoRelevantException
永远不会 return.
因此,它认为 code-path 在 try
块之后继续。所以你必须输入 "dead-code" return null
(或 throw new RuntimeException("should never come here")
.
不必放在try
块之后,可以放在catch
.
块里面
try {
responseCode = customReportConnection.getResponseCode();
return httpResponseBodyExtractor.extractResponseBodyFrom(customReportConnection);
} catch (IOException e) {
translateIntoRelevantException(responseCode, e);
throw new RuntimeException("should never come here");
}
让助手只 return
异常而不是抛出它可能更漂亮。然后你可以做
throw translateIntoRelevantException(responseCode, e);
getCustomReportResponse
的编译不应依赖于 translateIntoRelevantException
的实现,原因有多种:
translateIntoRelevantException
的实现可能不可用(它可能在单独的 class 中,在单独的库中);
- 否则
translateIntoRelevantException
中的任何更改都可能破坏所有调用方法。
作为替代方案,您可以 return 一个异常,然后将其抛出到客户端代码中:
private IOException translateIntoRelevantException(int responseCode, IOException e) {
if(is5xxResponseCode(responseCode)) {
return new ServerResponseException("Could not generate report - returned response code " + responseCode, e);
}
return new ReportException("GeminiReportException: Unable to parse response from HTTP body when requesting custom Gemini report.", e);
}
然后这样称呼它:
throw translateIntoRelevantException(responseCode, e);
我有一个关于 Java 方法内省的问题,特别是关于异常的问题。假设我有以下代码:
private String getCustomReportResponse(HttpsURLConnection customReportConnection) {
int responseCode = 0;
try {
responseCode = customReportConnection.getResponseCode();
return httpResponseBodyExtractor.extractResponseBodyFrom(customReportConnection);
} catch (IOException e) {
translateIntoRelevantException(responseCode, e);
}
}
假设 try 块中的两个语句都能够抛出 IOException - 在这种情况下,将调用 translateIntoRelevantException
方法,如下所示:
private void translateIntoRelevantException(int responseCode, IOException e) {
if(is5xxResponseCode(responseCode)) {
throw new ServerResponseException("Could not generate report - returned response code " + responseCode, e);
}
throw new ReportException("GeminiReportException: Unable to parse response from HTTP body when requesting custom Gemini report.", e);
}
因此,无论发生什么情况,要么 returned 字符串,要么抛出异常。除了 getCustomReportResponse
方法不在 catch 块后添加 return 语句就无法编译,这是绝对无法访问的。事实上,如果我将 translateIntoRelevantException
的内容放入 catch 块中,它会编译,这对我来说似乎很愚蠢。
我应该补充一下,抛出的异常是运行时异常,但我也试过让它们成为检查异常,但问题仍然存在。
谁能解释一下为什么?
这是 "rethrow" 辅助方法所面对的 common problem。
编译器不知道(也没有办法表明)方法 translateIntoRelevantException
永远不会 return.
因此,它认为 code-path 在 try
块之后继续。所以你必须输入 "dead-code" return null
(或 throw new RuntimeException("should never come here")
.
不必放在try
块之后,可以放在catch
.
try {
responseCode = customReportConnection.getResponseCode();
return httpResponseBodyExtractor.extractResponseBodyFrom(customReportConnection);
} catch (IOException e) {
translateIntoRelevantException(responseCode, e);
throw new RuntimeException("should never come here");
}
让助手只 return
异常而不是抛出它可能更漂亮。然后你可以做
throw translateIntoRelevantException(responseCode, e);
getCustomReportResponse
的编译不应依赖于 translateIntoRelevantException
的实现,原因有多种:
translateIntoRelevantException
的实现可能不可用(它可能在单独的 class 中,在单独的库中);- 否则
translateIntoRelevantException
中的任何更改都可能破坏所有调用方法。
作为替代方案,您可以 return 一个异常,然后将其抛出到客户端代码中:
private IOException translateIntoRelevantException(int responseCode, IOException e) {
if(is5xxResponseCode(responseCode)) {
return new ServerResponseException("Could not generate report - returned response code " + responseCode, e);
}
return new ReportException("GeminiReportException: Unable to parse response from HTTP body when requesting custom Gemini report.", e);
}
然后这样称呼它:
throw translateIntoRelevantException(responseCode, e);