有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

考虑下面的代码:

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() {}; 
}

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

public class B extends A implements I3 {

    @Override
    protected void bar4() {}

    public void bar1()  {}

}

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


共 (2) 个答案

  1. # 1 楼答案

    重写时,不能抛出范围更广或更新的异常。不抛出超类方法的异常是允许的

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

  2. # 2 楼答案

    继承可以使函数更具体

    您可以减少抛出的内容的数量,可以返回返回类型的子类型,可以接受参数类型的超类型

    这是因为对你的方法的任何可能的调用大多数都是对超级方法的合法调用,但反过来不一定是真的

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

    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,你就不会发现其他异常