2

假设 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):
}
4

3 回答 3

11

是的。这是正确的。重载总是静态解决。

您的后两个示例都不会编译为e's static type is Exception,并且您的重载都不接受该类型。

编辑:

请注意,您的最后一个示例并不是 try/catch 块的直接模拟。在 try/catch 中,您有两个名为 的变量e:每个 catch 一个,它们的静态类型分别是InvalidResourceExceptionResourceException。在您的最后一个示例中,您有一个名为 的变量e,其静态类型为Exception。如果您添加了新变量并使用强制转换分配给它们,那么您将获得与 try/catch 相同的行为(尽管您必须丢失最后的 else 分支)。

于 2009-11-25T19:35:59.707 回答
1

关于您问题的第一部分,正确的调用方法是在编译时根据变量声明的类型确定的。例如,如果您将 catch 语句更改为捕获 InvalidResourceException,则将改为调用 handleException(InvalidResourceException) 重载。

关于您问题的第二部分,JVM 只是找到能够处理抛出的异常的第一个 catch 语句。如果您要抛出 ResourceException,则将执行第二个 catch 块。

第三部分无法编译,因为不存在合适的 handleException() 方法来处理普通异常。

由于与第三部分相同的原因,最后一部分也将无法编译。

于 2009-11-25T19:55:10.510 回答
0

您正在期待 java 不支持的称为“双重调度”的东西。

于 2009-11-25T22:11:49.870 回答