我理解,如果检查方法覆盖对象而不是类型
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:为什么从A级引用play()?
怀疑2:为什么编译错误?
答案 0 :(得分:1)
obj是Eliminated类型,它扩展了A,因此它可以被A类变量引用。
编译错误在obj.play()中,因为您没有捕获它抛出的异常。由于obj被声明为类型A,因此编译器期望您处理它可能抛出的两种类型的异常。它不知道在实践中这些异常永远不会抛出。如果您将obj声明为已消除,则错误将消失。
答案 1 :(得分:1)
回答怀疑1:由于你有类型A的引用,编译器引用了类型引用的方法,即类A的play()方法。它在运行时解析为实际的,即它是类消除的。
怀疑2:Play方法抛出一个已检查的异常,因此它需要通过调用方法来表现。这里引用了A类的play()方法,它抛出异常,因此应该处理它。
答案 2 :(得分:1)
A是超类,因此可以引用任何级别的子类对象。它将调用您提供的“消除”类的方法。
更新该行 从 public static void main(String [] args)to public static void main(String [] args)抛出SuperException,AnotherException 将消除异常,因为play方法本身抛出了异常。或者你必须在main方法中尝试catch,因为它被检查异常,在编译时由编译器检查。
答案 3 :(得分:0)
Run-Time Evaluation of Method Invocation
在运行时,方法调用需要五个步骤。首先是目标 可以计算参考。其次,参数表达式是 评估。第三,要调用的方法的可访问性是 检查。第四,要执行的方法的实际代码是 位于。第五,创建一个新的激活帧,同步是 必要时执行,并将控制转移到方法代码。