Java认证:如何覆盖定义抛出异常的方法?

时间:2014-03-18 14:11:25

标签: java exception scjp

任何人都可以确认以下关于定义方法重写时抛出的异常的方法吗?我想确保我清楚地理解它。

给出以下代码:

class A
{
    public void doStuff() throws IllegalArgumentException{}
}

class B extends A
{
        public void doStuff() throws NumberFormatException{}
}

class C extends A
{
        public void doStuff() throws Exception{}
}

只有A类和B类应该编译而不是C类。当覆盖一个方法时,你可以缩小抛出的类,但是不能像C类那样扩展它。我相信这背后的原因是以下代码中的例子: / p>

class D
{
    doIt(A a)
    {
        try
        {
            a.doStuff();
        }
        catch(IlligalArgumentException e){}
    }
}

A类可以被扩展任意次,因此doStuff()方法也可能被覆盖任意次,但无论如何,上面的try catch总是会捕获异常。

但是如果允许扩展,上面的代码可能会错过抛出的异常,并且应用程序中会出现意外结果。

这是正确的想法吗?还有什么我想念的吗?

由于

2 个答案:

答案 0 :(得分:1)

如果方法声明抛出给定的异常,则子类中的重写方法只能声明抛出该异常或其子类。这是因为多态性。 所以imo,你的想法是正确的。

答案 1 :(得分:1)

作为参考,Java Language Specification

  

覆盖或隐藏其他方法的方法,包括方法   实现接口中定义的抽象方法,可能不是   声明抛出比被覆盖的或更多的已检查异常   隐藏方法。

  

更准确地说,假设B是一个类或接口,A是一个   B的超类或超接口,以及n中的方法声明B   覆盖或隐藏m中的方法声明A。然后:

     
      
  • 如果n有一个throws子句,提到任何已检查的异常类型,   然后m必须有一个throws子句,否则会发生编译时错误。

  •   
  • 对于n的throws子句中列出的每个已检查异常类型,   必须出现相同的异常类或其中一个超类型   删除m的throws子句(第4.6节); 否则,编译时   发生错误。

  •   
  • 如果m的未删除的throws子句不包含超类型   n的throws子句中的每个异常类型,编译时   发生未经检查的警告。

  •   

因此规则适用于已检查的异常类型,而不是未选中。