我不明白何时使用多捕获。我看到一些帖子,编译时间类型的多捕获异常是最接近的超类型的多个异常类型。
假设有异常类型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}
在哪些理想场合,我们应该在抛出多个异常时使用上述选项?
答案 0 :(得分:7)
根据Oracle documentation,新的多捕获块的显着点是:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
如果catch块处理多个异常类型,则catch参数为隐式最终。在此示例中,catch参数ex是final,因此您无法在catch块中为其分配任何值。通过编译处理多个异常类型的catch块生成的字节码将比编译许多每个只处理一种异常类型的catch块更小(因而更优越)。处理多个异常类型的catch块在编译器生成的字节码中不会产生重复;字节码没有异常处理程序的复制。
如果可以不同方式处理异常,那么我相信您应该单独捕获它们。如果异常处理对于多个异常是相同的,那么您可以使用多捕获块。
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 :(得分:3)
选项1:如果A
和B
的处理方式相同,请避免重复代码。
} catch (SSLException | UnknownHostException e) {
showErrorPopupAndReturn();
}
选项2:与选项1几乎相同,但它也会处理您可能不需要的任何其他C
子类型。
} catch (IOException e) {
// Almost as Option 1, but will also handle any other subclass of
// IOException, e.g. ObjectStreamException
doStuff();
}
选项3 :A
或B
发生时,您必须执行其他操作。
} catch (UnknownHostException e) {
tryAnotherIPaddress();
} catch (SSLException e) {
reloadCertificate();
}
答案 2 :(得分:0)
何时使用每个选项:
选项1 :A或B没有共同的超类,但处理它们的代码将是相同的
选项2 :A和B将C作为常见的超类,你只是不介意并将它们视为同一个
选项3 :A必须与B
区别对待答案 3 :(得分:0)
这取决于你如何处理异常。
案例1和案例3的最终结果是相同的。但在案例3中,代码的可理解性或可读性会增加在案例1中捕获两种类型的异常并处理
在第2种情况下,只捕获类型C,它的子类型异常和 处理
案例3 A和B两种类型分开处理。