方法覆盖异常处理 - 编译器在运行时多态性中的作用?

问题描述

请考虑此代码段,该代码段演示了覆盖异常处理的方法。 我知道与超类方法相比,子类覆盖的方法不能声明更广泛的异常。 我只是想知道为什么制定这个规则?

我的理解...

让我们假设,子类方法声明一个更广泛的异常是有效这样的 -

class Parent
{
  public void disp() throws IOException
  {
    System.out.println("Parent disp()");
  }
}

class Child extends Parent
{
  public void disp() throws Exception //widening
  {
    System.out.println("Child disp()");
  }
}

并且使用多态,当使用这样的父引用调用方法时。

Parent p = new Child();
p.disp();

在这种情况下,我相信编译器不会查看 Child 类重写的方法,而是基于引用类型(这里是“Parent”),它会查看 Parent 类的 disp() 方法。根据该方法的签名(准确地说,抛出 IOException),它会迫使程序员在进行调用时处理异常,就像这样。

try
{
  p.disp();
}
catch(IOException e)
{
  //handling code
}

现在问题来了,在运行时,方法调用显然会与 Child 类重写的 disp() 方法绑定。但是这个方法在它的签名中声明了一个更广泛的异常,不幸的是它不能被catch块处理,因为catch块可以处理指定参数类型(这里是IOException)的异常的所有子类型,但不能处理超类型。

显然,IOException 无法处理异常类型。 因此,子类中的重写方法不能声明更广泛的异常。但可以声明窄异常类型。

由于与子类重写方法相比,编译器会考虑声明更广泛异常的父类方法,因此catch块可以轻松处理在重写方法中声明的异常的任何子类型。

请承认到目前为止我的理解是否正确。

如果是对的,那么可以得出以下结论:

方法覆盖的情况下,

  1. 在编译期间,编译器会根据引用类型而不是实例的类型来考虑方法。所以,它当然是 Parent 方法,遵守方法覆盖的规则。
  2. 但是在运行时,JVM 会根据实例类型决定要调用方法

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...