在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
Julat pengecualian yang dilemparkan oleh kaedah subkelas tidak boleh melebihi julat pengecualian yang dilemparkan oleh kaedah kelas induk dan subkelas tidak perlu membuang pengecualian
Kelas pelaksanaan antara muka mungkin tidak membuang pengecualian, atau mungkin membuang pengecualian yang berbeza daripada antara muka Tetapi ia mestilah pengecualian yang ditakrifkan oleh antara muka atau subkelas pengecualian 🎜>
, tetapi juga melaksanakan antara muka
StormyInning
KaedahInning
dalamStorm
mengisytiharkan bahawa pengecualian yang dilemparkan ialahInning
dan kaedahevent()
dalam <.> antara muka Isytiharkan pengecualian yang dilemparkan sebagaiBaseballException
Jika anda hanya mewarisiStorm
, maka tiada masalah untuk membuangevent()
pengecualian,RainedOut
juga melaksanakan antara mukaInning
, kemudian membuangBaseballException
. pengecualian Ia tidak akan berfungsiStormyInning