Thinking In Java 异常这一节的这是不是错了?
PHPz
PHPz 2017-04-18 09:48:16
0
1
420

在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

PHPz
PHPz

学习是最好的投资!

répondre à tous(1)
刘奇
  1. La plage d'exceptions levées par la méthode de la sous-classe ne peut pas dépasser la plage d'exceptions levées par la méthode de la classe parent, et la sous-classe n'a pas besoin de lever des exceptions

  2. La classe d'implémentation de l'interface ne peut pas lever d'exception, ou elle peut lancer une exception différente de l'interface. Mais il doit s'agir d'une exception définie par l'interface ou d'une sous-classe de l'exception ; 🎜>

hérite non seulement de

, mais implémente également l'interface StormyInning. La méthode Inning dans Storm déclare que l'exception levée est Inning et la méthode event() dans <.> interface Déclarez l'exception levée comme BaseballException Si vous héritez simplement de Storm, alors ce n'est pas un problème de lancer l'exception event(). Cependant, RainedOut implémente également l'interface Inning, puis lancez BaseballException. exception, ça ne marchera pasStormyInning

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal