什么时候使用try multi catch?

我不明白何时使用多捕获。 我看到一些post,编译时间类型的多捕获exception是最接近的超类型的多个exception类型。

可以说有exception类型A,B和它们最接近的超类型C.

选项1

try{//whatever} catch(A|B ex){//whatever} 

选项2

 try{//whatever} catch(C ex){//whatever} 

选项3

 try{//whatever} catch(A ex){//whatever} catch(B ex){//whatever} 

在抛出多个exception时,我们应该在哪些理想情况下使用上述选项?

根据Oracle文档 ,新的多捕获块的显着点是:

 catch (IOException|SQLException ex) { logger.log(ex); throw ex; } 

如果catch块处理多个exception类型,则catch参数隐式为final 。 在此示例中,catch参数ex是final,因此您无法在catch块中为其分配任何值。 通过编译处理多个exception类型的catch块生成的字节码比编译许多每个只处理一种exception类型的catch块更小(因而更优越)。 处理多个exception类型的catch块不会在编译器生成的字节码中产生重复; 字节码没有exception处理程序的复制。

如果可以不同的方式处理exception,那么我相信您应该单独捕获它们。 如果exception处理对于多个exception是相同的,那么您可以使用多捕获块。

 try{//whatever} catch(A ex){//do something specific for A} catch(B ex){//do something specific for B} try{//whatever} catch(C ex){ //C is superclass of A and B and you are not concerned about the specific type // will catch even other exceptions which are instanceof C } try{//whatever} catch(A|B ex){//do the same thing for both A and B} 

选项1:避免重复代码,如果AB将以相同的方式处理。

 } catch (SSLException | UnknownHostException e) { showErrorPopupAndReturn(); } 

选项2:几乎与选项1相同,但它也将处理您可能不需要的任何其他C类型。

 } catch (IOException e) { // Almost as Option 1, but will also handle any other subclass of // IOException, eg ObjectStreamException doStuff(); } 

选项3:AB出现时,您必须做其他事情。

 } catch (UnknownHostException e) { tryAnotherIPaddress(); } catch (SSLException e) { reloadCertificate(); } 

何时使用每个选项:

选项1 :A或B没有共同的超类,但处理它们的代码将是相同的

选项2 :A和B将C作为常见的超类,你只是不介意并将它们视为相同

选项3 :A必须与B不同

这取决于您如何处理exception。

在案例1中捕获和处理两种类型的exception

在情况2中,它只被捕获类型C,它的子类型exception和句柄

在案例3中,A和B两种类型分别处理。

案例1和案例3的最终结果是相同的。 但在案例3中,代码的可理解性或可读性将会增加