Java 如果throws子句只列出抛出异常的超类型,抛出异常是否保留其类型
我有以下代码,它们分析了java异常处理的基本行为(java 7之前的版本,不尝试使用资源或多捕获或其他) 我创建了一个自定义异常层次结构来测试这个类,它位于文件的底部Java 如果throws子句只列出抛出异常的超类型,抛出异常是否保留其类型,java,exception,exception-handling,Java,Exception,Exception Handling,我有以下代码,它们分析了java异常处理的基本行为(java 7之前的版本,不尝试使用资源或多捕获或其他) 我创建了一个自定义异常层次结构来测试这个类,它位于文件的底部 public class Rethrow { public void method1() throws MyExceptionSub1 {} public void method2() throws MyExceptionSub2 { try { method1(); } catc
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 {}
我特别想知道:
当一个方法声明抛出一个异常时,即使它抛出该异常的子类,该异常仍保留其类型并被其相应的catch块捕获(这就是为什么我通常使用catch块的类型比try块中的方法声明的类型更具体)
当在catch块内(其行为类似于方法,带有exception参数和all)时,异常保留其类型(如果是rethrown,编译器希望我处理或声明原始异常,即使是在包含更广泛异常的catch内),但它被视为catch参数(我不能在catch子句中调用特定的方法)
这有点令人困惑
我添加了一些注释以澄清我的假设(这些假设已被编译器确认,但请告诉我我是对还是错)
当一个方法声明抛出一个异常时,即使它抛出该异常的子类,该异常仍保留其类型并被其相应的catch块捕获(这就是为什么我通常使用catch块的类型比try块中的方法声明的类型更具体)
是的。对象将一如既往地保留其实际类型
当在catch块内(其行为类似于方法,带有exception参数和all)时,异常保留其类型(如果是rethrown,编译器希望我处理或声明原始异常,即使是在包含更广泛异常的catch内),但它被视为catch参数(我不能在catch子句中调用特定的方法)
是的。参数的声明一如既往地适用。Java不是一种动态类型的语言。如果使用
对象类型的参数声明方法,并向其传递字符串类型的变量,则只有在不使用强制类型转换的情况下,才能对其调用对象类型的方法。您可以检查变量是一个字符串
,使用instanceof
,将其转换为字符串
,并调用字符串
的方法
异常的行为方式完全相同。catch
子句使用子句中指定的类型有效地执行instanceof
检查,并声明该类型的参数。此参数中存储的实际变量可以与catch子句的参数具有不同的运行时类型。是,但“一如既往”在这里应用有点棘手。对象始终保留其动态类型,但当它传递给从方法返回的对象时,其静态类型可能会有所不同(向上转换)。throws and catch子句不是这样的,不是吗?总是这样。我不明白你为什么不这么认为,或者为什么你认为它“棘手”。这不是。另请参见