在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 ofevent()
in Inning.
就是说接口不能改变父类里相同方法的异常接口,给人一种子类的抛的异常就得按父类,而不按接口来的感觉。但事实上经过测试之后,子类的event方法只有不抛异常,抛RuntimeException和抛Error才能行。抛BaseballException会报错。
所以感觉作者是不是在这讲错了。用的环境是JDK1.8
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
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 ; 🎜>
, mais implémente également l'interface
StormyInning
. La méthodeInning
dansStorm
déclare que l'exception levée estInning
et la méthodeevent()
dans <.> interface Déclarez l'exception levée commeBaseballException
Si vous héritez simplement deStorm
, alors ce n'est pas un problème de lancer l'exceptionevent()
. Cependant,RainedOut
implémente également l'interfaceInning
, puis lancezBaseballException
. exception, ça ne marchera pasStormyInning