多捕获块中的引用类型的exception问题
e的类型为Exception,但在下面的代码中打印Exception1:
class Exception1 extends IOException {void info(){}} class Exception2 extends Exception {} class TestMultiCatch { public static void main(String args[]) { try { int a = 10; if (a <= 10) throw new Exception1(); else throw new Exception2(); } catch (Exception1 | Exception2 e) { e.info(); //line 1 error "The method info() is undefined for type Exception" System.out.println(e); //prints Exception1 (after commenting line 1) } } }
从我研究的“e”应该是Exception类型,它是Exception1和Exception2的通用基类。 从第1行的消息可以看出它是什么。
但那么为什么:
System.out.println(e); //prints Exception1 and not Exception System.out.println(e instanceof IOException); //prints true and not false System.out.println(e instanceof Exception1); //prints true and not false System.out.println(e instanceof Exception2); //false
? 谢谢。
当你使用multi-catch子句 ( catch的Exception1 | Exception2 e
forms)时, Exception1 | Exception2 e
的编译时类型是两种类型共有的最大类型,因为代码当然必须处理任何一种类型的exception从规格 :
exception参数可以将其类型表示为单个类类型或两个或更多类类型的联合(称为替代)。 联合的替代方法在语法上由
|
分隔 。将其例外参数表示为单个类类型的catch子句称为uni-catch子句 。
一个catch子句,其exception参数表示为类型的并集,称为multi-catch子句 。
…
声明的exception参数类型,表示其类型为与备用
D1 | D2 | ... | Dn
D1 | D2 | ... | Dn
D1 | D2 | ... | Dn
是lub(D1, D2, ..., Dn)
。
…这里定义的lub
是最小上界。
如果要使用特定于Exception1
或Exception2
任何内容,请使用单独的catch
块:
} catch (Exception1 e) { // Something using features of Exception1 } catch (Exception2 e) { // Something using features of Exception2 }
如果Exception1
和Exception2
上都存在info
,则重构它们以便info
存在于它们的共同祖先类中:
class TheAncestorException extends Exception { public void info() { // Or possibly make it abstract // ... } } class Exception1 extends TheAncestorException { // Optionally override `info` here } class Exception2 extends TheAncestorException { // Optionally override `info` here }
…所以编译器可以给出类型TheAncestorException
并使info
可访问。
多次捕获似乎是你的问题。 您(编译器)只能访问在共同祖先上定义的方法。 当然,“e”在运行时将是Exception1,但编译器不能假设它,因为它也可能是Exception2。 最好为Exception1和Exception2创建一个catch块。
catch (Exception1 | Exception2 e) {....}
这里e
是Exception1和Exception2的引用变量。 所以在编译时e.info();
将抛出exception,因为对于Exception2
info()
不存在。
最好为每个类使用单独的catch块,因为两个类都没有相同的方法info()
。
} catch (Exception1 e) { e.info(); System.out.println(e); } catch (Exception2 e) { System.out.println(e); }
- class not found exception com.mysql.jdbc.driver
- 为什么hibernate将HibernateException更改为(未选中)RuntimeException
- 不能使用try / catch块处理java未经检查的exception?
- 如何不抛出一般指定的exception?
- Apache Hadoop setXIncludeAware UnsupportedOperationException
- Javaexception命名约定
- javax.persistence.NoResultException:getSingleResult()没有检索任何实体
- 为什么UmbrellaException有这个名字?
- java.util.ConcurrentModificationException&iteration?