为什么我可以在没有“throws”关键字的情况下声明一个函数?

时间:2014-07-03 13:42:38

标签: java oop exception inheritance interface

请考虑以下代码:

public interface I1 {
 public void bar1() throws IOException; 
} 

public interface I2 extends I1 { 
 public void bar2() throws Exception; 
} 

public interface I3 { 
 public void bar3() throws Exception; 
} 

public abstract class A implements I2 { 
 public void bar2() throws Exception{}; 
 public void bar3() throws Exception{}; 
 protected abstract void bar4(); 
 protected void bar5() {}; 
}

现在,我创建了一个类B,如下所示:

public class B extends A implements I3 {

    @Override
    protected void bar4() {}

    public void bar1()  {}

}

为什么编译器会让我这样做?我的意思是,不应该是:
public void bar1() throws IOException;

2 个答案:

答案 0 :(得分:1)

继承可让您使功能更具体。

你可以减少你抛出的东西,你可以返回一个返回类型的子类型,你可以接受一个参数类型的超类型。

这是因为对您的方法的任何可能调用大多数是对super方法的合法调用,但反过来不一定是真的。

换句话说,在你的例子中:

new B().bar1() 

你知道它并没有抛出异常,你不需要抓住。

((A)new B()).bar1()

您需要捕获异常,因为您现在正在处理A的任何A或子类,您可能需要处理它。

如果您尝试反过来并创建一个C类:

public class C extends A implements I3 {

    @Override
    protected void bar4() {}

    public void bar1() throws IOException, SomeOtherException {}

}

如果您尝试将C用作A而不会捕获SomeOtherException,则不允许这样做。

答案 1 :(得分:1)

覆盖时,不能抛出更大或更新的异常。不允许抛出超类方法的异常。

重写方法不得抛出新的或更广泛的已检查异常,而不是被重写方法声明的异常。例如,声明FileNotFoundException的方法不能被声明SQLException,Exception或任何其他非运行时异常的方法覆盖,除非它是FileNotFoundException的子类。