重写的方法不能抛出exceptionJava

这是我的代码块。

class Alpha{ public void Gamma() { System.out.println("Alphas"); } } class Beta extends Alpha{ public void Gamma() throws Exception //Line 1 { try { System.out.println("Betas"); } catch(Exception e) { System.out.println("Exception caught"); } finally { System.out.println("xfg"); } } public static void main(String[] args) throws Exception { Alpha g = new Beta(); g.Gamma(); } } 

此代码无法编译,因为我在Line1中添加了“throws”。

编译器抱怨重写的方法不能抛出exception。

为什么这样 ?。

为什么不能重写方法抛出exception?

因为我可以通过在子类的实现中添加n行代码来覆盖基类中的方法。

这些添加的代码可以抛出一个exception,为什么我不能在重写方法中使用“throws”?

重写的方法可以抛出exception,只要被覆盖的方法也抛出相同的exception。 您无法引入新的例外。

那你为什么不能引入一个新的例外呢?

OOP的核心概念之一是使用抽象类型,并且所有子类型都可以被视为抽象类型。 见Liskov替代原则

您不能引入更广泛行为的原因是,如果抽象类型(超类或接口)中的方法不会抛出exception并且您将对象称为该类型,则会出现意外行为:

 Alpha alpha = new Beta(); // At this point, the compiler knows only that we have an Alpha alpha.myMethod(); 

如果Alpha的myMethod()没有抛出exception,但Beta会抛出exception,我们可能会在上面的代码中遇到意外的exception。

子类overriden方法只能抛出(Declare) 未经检查的exception,如ArrayIndexOutOfBoundsException。

但是您不能抛出(声明)已检查的exception。 像IOException。

verriden方法的示例抛出exceptionJava

 class A{ public void show(){ // some code here } } class B extends A{ public void show() throws ArrayIndexOutOfBoundsException{ // some code here } } 

希望这些可以帮到你。

您的客户端总是考虑处理基本版本。 这就是多态性的全部好处=>客户端忽略了覆盖的一个。

因此,没有什么会强迫客户端处理由覆盖所做的特定规则,这里是由覆盖方法抛出的潜在exception的情况。

这就是为什么覆盖方法不能抛出更广泛的exception。 这会破坏合同。

因此,关于这个逻辑,规则是: Overriden方法CAN(如果需要)只抛出在基本版本中声明的exception的子部分但是不能抛出更宽的部分。

规则说

“子类重写方法不能抛出比超类方法更多的exception”。

编译器抱怨重写的方法不能抛出exception

不,不。 再次阅读该消息。 它表示你不能抛出一个未被声明被重写方法抛出的exception。 根本不是一回事。

您在main方法中的上述代码

Alpha g = new Beta(); //现在它创建了一个新的Beta类的实际对象,并引用了Alpha

g.Gamma(); // *现在编译器看起来只有Gamma()方法在Alpha类中提供了它在Beta类中出现的默认情况下它仍然通过inheritance。但是编译器只查看类Alpha并且问一个问题是包含一个方法Gamma()并找到答案是的,它有。

假设java编译器提供的工具在Beta类的 gamma()方法中抛出更多已检查的exception,那么将会发生什么

  • 现在在编译时编译器只依赖于类Alpha的Gamma()方法。它不强制处理此exception或抛出这个错误,因为它可能抛出(假设java编译器允许在重写方法中抛出更多的已检查exception)。 但实际上编译器不会对抛出exception以及可访问性修饰符进行限制。

    因为非静态方法调用发生在实际的对象方法而不是类型上,我们给任何超类型,并且在编译时编译器只检查该类型的已分配类的可访问性和存在性。

所以我认为这就是这个被超越的合同背后的原因

•方法定义不能缩小方法的可访问性,但可以扩展它。 •方法定义只能抛出超类中重写方法的throws子句中指定的全部或全部或已检查exception(包括其子类)的子集。