假设InvalidResourceException是ResourceException的子类。定义两种方法:
void handleException(ResourceException e) {
System.out.println("ResourceException " + e.toString());
}
void handleException(InvalidResourceException e) {
System.out.println("InvalidResourceException " + e.toString());
}
现在输入以下代码:
try {
throw new InvalidResourceException("invalid resource");
} catch (ResourceException e) {
handleException(e);
}
打印出来:
ResourceException: com.myPackage.InvalidResourceException: invalid resource
但是以下代码:
try {
throw new InvalidResourceException("invalid resource");
} catch (InvalidResourceException e) {
handleException(e);
} catch (ResourceException e) {
handleException(e);
}
打印出来:
InvalidResourceException: com.myPackage.InvalidResourceException: invalid resource
这是Sun的JDK 1.5.0_15。
这是否符合Java标准?
这段代码应该做什么?
Exception e = new InvalidResourceException("invalid resource");
handleException(e);
这段代码应该做什么?
Exception e = new InvalidResourceException("invalid resource");
if (e instanceOf ResourceException) {
handleException(e);
} else if (e instanceOf InvalidResourceException) {
handleException(e);
} else {
handleException(e):
}
答案 0 :(得分:11)
是。这是正确的。过载总是静态解决。
后两个示例都不会编译为e
的静态类型为Exception
,并且您的任何重载都不接受该类型。
修改强>
请注意,您的最后一个示例实际上并不是try / catch块的直接模拟。在try / catch中,您有两个名为e
的变量:每个catch一个,其静态类型分别为InvalidResourceException
和ResourceException
。在最后一个示例中,您有一个名为e
的变量,其静态类型为Exception
。如果您添加了新变量并使用强制转换分配给它们,那么您将获得与try / catch相同的行为(尽管您必须丢失最后的其他分支)。
答案 1 :(得分:1)
关于问题的第一部分,调用的正确方法是在编译时根据变量声明的类型确定的。例如。如果你改变了catch语句以捕获InvalidResourceException,那么将调用handleException(InvalidResourceException)重载。
关于问题的第二部分,JVM只是找到能够处理抛出的异常的第一个catch语句。如果你要抛出一个ResourceException,那么第二个catch块就会被执行。
第三部分不会编译,因为没有合适的handleException()方法来处理普通的异常。
由于与第三部分相同的原因,最后一部分也将无法编译。
答案 2 :(得分:0)
你期待一种叫做“双重调度”的东西,这是java不支持的。