处理 Java 中相同类型的不同异常?

Handling different exceptions of the same type in Java?

在 Java 中处理错误时,通常会看到超类是被捕获的错误,例如

Exception, IOException, SocketException, etc.

但是,您如何找到异常的具体细节?您如何从其他异常类型中挑选出某种异常类型。例如,我目前正在使用 Netty.io 开发一个小项目,它会为您可以命名的每种类型的 read/write 错误抛出 IOException。这是有道理的,因为最终这是 input/output 个错误,但我将如何单独处理它们。

例外示例:

java.io.IOException: An existing connection was forcibly closed by the remote host
java.io.IOException: Connection reset by peer
java.io.IOException: Stream closed

这个列表还在继续,但是你将如何单独处理这些,我在环顾四周时发现的一种方法似乎真的很讨厌,如下所示。

try { 
    // ...
} catch (IOException e) { 
    if(e.getMessage().contains("An existing connection was forcibly closed by the remote host")) {
        // Handle error
    } else //...
}

这看起来很乏味,肯定有更好的方法来做到这一点,如果您愿意,可以使用 correct 方法。在过去的几个小时里,我浏览了很多关于错误处理的文章,它们都只谈论常用的大男孩。 IOException, Exception, SocketException, NullPointerException, and FileNotFoundException。我认为 SocketExceptionFileNotFoundExceptionIOException 直接相关,很可能是一个子类,如果我错了请纠正我。

无论如何,处理这些异常的正确方法是什么?您如何确定需要处理的异常类型?我真正能做的就是处理 IOException 直到出现更精确的东西,但是在开发应用程序时,能够唯一地处理每个错误总是好的。

在大多数情况下,从代码的角度来看,消息是无关紧要的。它只是要向用户显示或记录的内容。唯一突出的事实是连接已断开,无论出于何种原因,并且没有不同的代码路径可供您使用,具体取决于它是哪条消息。

唯一不同的是 'socket closed',表示存在编码错误。

编辑 关于您的以下评论:

  • 套接字上除 SocketTimeoutException 之外的任何 IOException 对连接都是致命的。
  • 无效数据包不会导致IOException:这是抛出应用层异常的应用层问题,或者IOException:的子类,例如java.io.StreamCorruptedException.
  • 没有IOException: connection closed by remote host这样的东西。如果对等方关闭连接,则会导致流结束条件,表现为 read() 返回 -1,readLine() 返回 null,或 readXXX() 抛出 EOFException 对于任何其他 X.

我建议按从最具体到最少的顺序捕获异常 - 这样当遇到您要查找的异常时,您会注意到熔断模式。这是我能想到的最好的:

try {
   /// Something that can result in IOException or a SocketException
catch (IOException e){
   //Do something specific
}catch (SocketExcpetion e){

}catch (Exception e) { //or some superclass of the above exceptions
 ///
}

不要忘记,您还可以使用 | 命令捕获多个不同类型的异常:catch (IOException|SocketException|

文档 (http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html) 包含一长串直接子类。您可能想要浏览它们并检查您想要区别对待哪些。 一旦知道这一点,就可以使用多个 catch 块,首先是子类,然后是最通用的 IOException:

catch(SSLException se) {
  // do something
}
catch(HttpRetryException he) {
  // do something else
}
catch(IOException ioe) {
  // nop
}