Java捕获块是否使用静态绑定?

Java捕获块是否使用静态绑定?,java,instanceof,Java,Instanceof,假设InvalidResourceException是ResourceException的子类。定义两种方法: void handleException(ResourceException e) { System.out.println("ResourceException " + e.toString()); } void handleException(InvalidResourceException e) { System.out.println("InvalidResourceE

假设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);
}
   try {
     throw new InvalidResourceException("invalid resource");
   } catch (InvalidResourceException e) {
     handleException(e);
   } catch (ResourceException e) {
     handleException(e);
   }
打印此文件:

ResourceException: com.myPackage.InvalidResourceException: invalid resource
InvalidResourceException:  com.myPackage.InvalidResourceException: invalid resource
但以下代码:

try {
  throw new InvalidResourceException("invalid resource");
} catch (ResourceException e) {
  handleException(e);
}
   try {
     throw new InvalidResourceException("invalid resource");
   } catch (InvalidResourceException e) {
     handleException(e);
   } catch (ResourceException e) {
     handleException(e);
   }
打印此文件:

ResourceException: com.myPackage.InvalidResourceException: invalid resource
InvalidResourceException:  com.myPackage.InvalidResourceException: invalid resource
这是Sun的JDK1.5.015

这与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):
}
这个代码应该做什么

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):
}

对。没错。重载总是静态解决的

后两个示例都不会编译为
e
的静态类型为
Exception
,并且两个重载都不接受该类型

编辑:


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

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

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

第三部分不会编译,因为没有合适的handleException()方法来处理普通异常


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

您期望的是java不支持的名为“双重分派”的东西。

这种行为对我来说似乎很有用。解决重载比简单的“静态”要复杂一些——还有一个动态方面。有关详细信息,请参阅。方法调用(链接到的JLS部分)有一个动态方面,但重载解析是一个严格的静态(即编译时)操作。事实上,您链接到的JLS部分支持这一点:唯一提到重载的部分(除了开头的概述)是§15.12.2,“编译时步骤2:确定方法签名”。