我有以下代码,它分析了java异常处理的基本行为(Java 7之前,没有try-with-resources或multi catch等)。
我创建了一个自定义异常层次结构来测试这个类,它位于文件的底部。
public class Rethrow {
public void method1() throws MyExceptionSub1 {}
public void method2() throws MyExceptionSub2 {
try {
method1();
}
catch (MyExceptionSubSub1 e) {} // catch MyExceptionSub1 and all its subclasses
catch (MyExceptionSub1 e) {}
//catch (MyException e) {} // unreachable catch clause
catch (Exception e) {} // catch block with Exception is always reachable (by unchecked exceptions)
throw new MyExceptionSub2();
}
public void method3() throws MyExceptionSub2 {
try {
method2();
}
catch (MyException e) { // even if MyExecptionSub2 is caught by a catch block with MyException it retains its original type...
e.printStackTrace();
//e.method(); // ...but inside the catch block is of type MyException
throw e;
}
}
public static void main(String... args) {
}
}
// Custom exceptions hierarchy
class MyException extends Exception {}
class MyExceptionSub1 extends MyException {}
class MyExceptionSub2 extends MyException {
public void method() { System.out.println("sub2"); }
}
class MyExceptionSubSub1 extends MyExceptionSub1 {}
特别是,我想知道这个:
当一个方法DECLARE抛出异常时,即使它是一个子类而不是该异常,该异常会保留其类型并被其相应的catch块捕获(这就是为什么我被赋予使用具有更多特定类型的catch块的原因比try块中的方法声明的那样?)
当在一个catch块(它的方法就像一个方法,带有exception参数和all)时,异常会保留它的类型(如果它被重新编译,编译器希望我处理或声明原始异常,即使在catch中有一个更广泛的例外)但它被视为catch参数(我不能调用catch子句中的特定方法)?
这有点令人困惑......
我添加了一些评论以澄清我的假设(由编译器确认,但请告诉我,我是对还是错)
答案 0 :(得分:0)
当一个方法DECLARE抛出一个Exception时,即使它是一个子类而不是异常,该异常会保留其类型并被其相应的catch块捕获(这就是为什么我可以使用它)捕获具有比try块中的方法声明的更具体类型的块??
是。该对象一如既往地保留其实际类型。
当在catch块内部(其作用类似于方法,带有exception参数和all)时,异常保留其类型(如果重新编译,编译器希望我处理或声明原始异常,即使在内部更广泛的例外)但它被视为catch参数(我无法调用catch子句中的特定方法)?
是。参数声明一如既往地适用。
答案 1 :(得分:0)
Java不是动态类型语言。如果您声明一个类型为Object
的参数的方法并向其传递String
类型的变量,那么如果您不这样做,则只能在其上调用Object
类型的方法使用演员表。您可以使用String
检查该变量是instanceof
,将其转换为String
,并调用String
的方法。
异常的行为方式完全相同。 catch
子句使用子句中指定的类型有效地执行instanceof
检查,并声明该类型的参数。存储在此参数中的实际变量可以与catch子句的参数具有不同的运行时类型。