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

在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

学习是最好的投资!

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!