开发者社区> 问答> 正文

Thinking In Java 异常这一节的这是不是错了? 报错

"

在Exception restrictions这一小节里边,里面有一大段代码

class BaseballException extends Exception {} class Foul extends BaseballException {} class Strike extends BaseballException {}

abstract class Inning { public Inning() throws BaseballException {} public void event() throws BaseballException { // Doesn’t actually have to throw anything } public abstract void atBat() throws Strike, Foul; public void walk() {} // Throws no checked exceptions }

class StormException extends Exception {} class RainedOut extends StormException {} class PopFoul extends Foul {}

interface Storm { public void event() throws RainedOut; public void rainHard() throws RainedOut; }

public class StormyInning extends Inning implements Storm { // OK to add new exceptions for constructors, but you // must deal with the base constructor exceptions: public StormyInning() throws RainedOut, BaseballException {} public StormyInning(String s) throws Foul, BaseballException {}

// Regular methods must conform to base class:
//! void walk() throws PopFoul {} //Compile error
// Interface CANNOT add exceptions to existing methods from the base class:
//! public void event() throws RainedOut {} //Compile error
// If the method doesn’t already exist in the
// base class, the exception is OK:
@Override
public void rainHard() throws RainedOut {}

// You can choose to not throw any exceptions,
// even if the base version does:
@Override
public void event() {}

// Overridden methods can throw inherited exceptions:
@Override
public void atBat() throws PopFoul {}

public static void main(String[] args) {
    try {
        StormyInning si = new StormyInning();
        si.atBat(); // Strike not thrown in derived version.
    } catch(PopFoul e) {    //caused by si.atBat();
        System.out.println("Pop foul");
    } catch(RainedOut e) {  //StormyInning()
        System.out.println("Rained out");
    } catch(BaseballException e) {  //StormyInning()
        System.out.println("Generic baseball exception");
    }
    
    try {
        // What happens if you upcast?
        Inning i = new StormyInning();
        i.atBat();
    // You must catch the exceptions from the
    // base-class version of the method:
    } catch(Strike e) {
        System.out.println("Strike");
    } catch(Foul e) {
        System.out.println("Foul");
    } catch(RainedOut e) {
        System.out.println("Rained out");
    } catch(BaseballException e) {
        System.out.println("Generic baseball exception");
    }
}

} ///:~

原来代码的这段注释

// You can choose to not throw any exceptions,
// even if the base version does:
@Override
    public void event() {}

你可以选择不抛出任何异常。那换而言之,我也可以根据父类来决定子类抛出哪些异常咯?比如抛出BaseballException,但我测试却不行。我觉得这里的注释是不是写得有点问题。
正常情况下这句话是对的,但这里还实现了Storm接口。

原文有这句话

When Stormylnning extends Inning and implements Storm, you’ll see that the event() method in Storm cannot change the exception interface of event() in Inning.

就是说接口不能改变父类里相同方法的异常接口,给人一种子类的抛的异常就得按父类,而不按接口来的感觉。但事实上经过测试之后,子类的event方法只有不抛异常,抛RuntimeException和抛Error才能行。抛BaseballException会报错。
所以感觉作者是不是在这讲错了。用的环境是JDK1.8

" ![image.png](https://ucc.alicdn.com/pic/developer-ecology/9109d299ef82404f840d73ab0b81e4c7.png)

展开
收起
因为相信,所以看见。 2020-05-26 13:56:45 767 0
1 条回答
写回答
取消 提交回答
  • 阿里,我所有的向往

    "

    1. 子类的方法抛出的异常范围不能超过父类的方法抛出的异常范围,子类也可以不抛出异常;

    2. 接口的实现类可以不抛异常,也可以抛出与接口不一样的异常. 但是必须是接口定义的异常或是该异常的子类;

    StormyInning不仅继承了Inning,也实现了Storm接口,Inning中的event()方法声明抛出的异常是BaseballException Storm接口中的event()方法声明抛出的异常为RainedOut,如果你只是继承了Inning,那么抛出BaseballException异常是没问题的,但是StormyInning还实现了Storm接口,那抛出BaseballException异常就不行了

    " ![image.png](https://ucc.alicdn.com/pic/developer-ecology/a9a164cebd4d4596ab8ac177b8a43ea8.png)
    2020-05-27 10:07:42
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载