2014-08-27 43 views
5

在Java中,我们可以捕捉特定类型的异常:Java的标识异常精确

try{ 
    // Code that does IO like download a file... 
}catch(IOException ioe){ 
    ioe.printStackTrace(); 
    // handle ioe 
}catch(SomeOtherException soe){ 
    // handle soe 
} 

现在,可以由很多原因一个例外,在这种情况下,IOException可以是:

java.io.IOException: Illegal character in path at index..... 
从特定库或一些其他类似的

java.io.IOException: Stream closed ... 

如果出现了一些问题a Stream

现在,我的问题是,我该如何确定发生什么样的IOException

如何区分Stream closedIllegal character in path at index...

当然,我可以检查异常消息的字符串,但我不认为这是最好的方式,因为底层库/实现可以更改消息字符串。

编辑:

e.getClass()在这种情况下,几乎一切恢复java.io.IOException ...

我猜库抛出自己IOException而丢弃任何原始Exception

回答

7

printStackTrace印刷

java.io.IOException: Stream closed ... 
//  ^^^^^^^^^^^ 

java.io.IOException: Illegal character in path at index..... 
//  ^^^^^^^^^^^ 

的事实意味着所述ExceptionIOException类型。没有更具体的子类型可以在这里使用。

在这种情况下没有办法。他们决定使用相同的Exception类型为(和更多)这些原因。您将无法将它们与不同的catch声明区分开来。你需要检查他们的消息。

如果Exceptioncause,您必须查看是否存在区分类型并重新抛出它。如果你幸运的话,你可能会抓到更具体的Exception

+2

我回复了你,因为这是看到'IOEeception'并知道它是一个具体类型的唯一答案。我不知道为什么有人会首先让你失望... – tom91136 2014-08-27 19:33:20

+0

@HovercraftFullOfEels'printStackTrace'方法取决于'toString'方法。 'Throwable'实现用'getClass()。getName()'打印类名。因此,除非'StreamClosedException'覆盖其'toString'来返回'IOException'类名,否则具体类型是'IOException'。 – 2014-08-27 19:42:30

+0

@SotiriosDelimanolis:道歉。 – 2014-08-27 19:43:36

4

您可以采用不同捕获的异常,因为IOException是子例外

的顶部层级从documentation

java.io.IOException 
    java.io.CharConversionException 
    java.io.EOFException 
    java.io.FileNotFoundException 
    java.io.InterruptedIOException 
    java.io.ObjectStreamException 
     java.io.InvalidClassException 
     java.io.InvalidObjectException 
     java.io.NotActiveException 
     java.io.NotSerializableException 
     java.io.OptionalDataException 
     java.io.StreamCorruptedException 
     java.io.WriteAbortedException 
    java.io.SyncFailedException 
    java.io.UnsupportedEncodingException 
    java.io.UTFDataFormatException 
    java.io.UnsupportedEncodingException 
    java.io.UTFDataFormatException 
+1

在OP案例中,异常的具体类型似乎是'IOException'。更具体的子类型将无济于事。 – 2014-08-27 19:27:53

+0

是的,我已经做了一个编辑,请检查更新的问题 – tom91136 2014-08-27 19:28:40

1

当一个库提出了一个过于通用的异常(如,看来,你”重新跑到这里与IOException)你不幸没有很多好的选择 - 基本上这是图书馆的一部分糟糕的设计。理想情况下,您应该提交错误或提交违规库的请求,但这可能不可行或不可行。

然而,一切都不会丢失。首先,图书馆实际上可能会给您提供比您想象的更多的信息,通过Throwable.getCause()包含通用的IOException潜在原因。这是提供更详细的调试信息的强大方式,同时公开单个Exception进行正常处理。如果该库采用这种做法,你可以这样做:

catch(IOException e) { 
    Throwable cause = e.getCause(); 
    if(cause != null && cause instanceof URISyntaxException) { 
    System.err.println("Bad URI"); 
    } else { 
    System.err.println("Other IOException"); 
    } 
} 

当然,把一些什么建议谷歌搜索是一个URISyntaxExceptionIOException是不是在首位非常好的设计(无效的URI当然不是IO问题),所以如果图书馆只是简单地调用诸如throw new IOException(e.getMessage())之类的东西并丢弃原文,我不会感到惊讶,这意味着不幸的是,所有你必须继续的是例外的信息。

就像你注意到的,解析异常消息并不是一个非常好的主意。理想情况下,您应该将这种不良行为包装到辅助方法中,以便在库改进后轻松地重构它,并检测是否有任何意外事件发生并解决它。试想一下:

public void doOperation(arguments) throws IOException, URISyntaxException { 
    try { 
    BadLibrary.doOperation(arguments); 
    } catch(IOException e) { 
    if(e.getMessage().startsWith("Illegal character")) { 
     throw new URISyntaxException("Uknown", e.getMessage()); 
    } else if(e.getMessage().startsWith("Stream closed")) { 
     throw e; 
    } else { 
     // note we include the cause here 
     throw new RuntimeException("Unexpected exception from BadLibrary", e); 
    } 
    } 
} 

有了这个划分,你只需要做到这一点不愉快的检查在一个地方,并且可以合理有信心,你会发现意想不到的改变底层库,而不是默默忽略他们。