0

我知道如果方法覆盖对象被检查而不是类型

class SuperException extends Exception {}
class SubException extends SuperException {}

class AnotherException extends Exception {}
class YetAnotherException extends Exception {}

class A {
  void play() throws SuperException, AnotherException {}
}
class Reduced extends A {
  void play() throws SuperException {} 
}
class Eliminated extends A {
  void play() {} 
}
class Narrower extends A {
  void play() throws SubException {}
}
class TestPolymorphism {
  public static void main(String[] args) {
    A obj = new Eliminated();
    obj.play();                         // Doubt 1
    Eliminated eobj = new Eliminated(); // Doubt 2
  }
}

疑问1:为什么play()是从A类引用的?

疑问2:为什么会出现编译错误?

4

4 回答 4

1
  1. obj 是扩展 A 的 Eliminated 类型,因此它可以由 A 类型的变量引用。

  2. 编译错误在 obj.play() 中,因为你没有捕捉到它抛出的异常。由于 obj 被声明为 A 类型,编译器希望您处理它可能抛出的 2 种异常类型。它不知道在实践中这些异常永远不会被抛出。如果您将 obj 声明为已消除,则错误将消失。

于 2013-03-24T13:51:12.140 回答
1

对疑问1的回答:由于您有类型A的引用,编译器引用了类型引用的方法,即A类的play()方法。它在运行时被解析为实际的,即它属于Eliminated类。

疑点2:play方法抛出checked异常,需要调用方法处理。这里引用了A类的play()方法,它抛出了异常,因此应该处理它。

于 2013-03-24T13:57:29.617 回答
1

A 是超类,因此可以引用任何级别的子类对象。它将调用您提供的“消除”类的方法。

将 public static void main(String[] args) 行更新为 public static void main(String[] args) throws SuperException,AnotherException 将消除该异常,因为该异常是由 play 方法本身引发的。或者你必须在 main 方法中尝试 catch,因为它是检查异常,由编译器在编译时检查。

于 2013-03-24T13:59:04.100 回答
0

方法调用的运行时评估

在运行时,方法调用需要五个步骤。首先,可以计算目标参考。其次,评估参数表达式。第三,检查要调用的方法的可访问性。第四,定位要执行的方法的实际代码。第五,创建新的激活帧,必要时进行同步,并将控制转移到方法代码。

于 2013-03-24T13:50:35.617 回答