"
在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
" ![image.png](https://ucc.alicdn.com/pic/developer-ecology/9109d299ef82404f840d73ab0b81e4c7.png)
"
子类的方法抛出的异常范围不能超过父类的方法抛出的异常范围,子类也可以不抛出异常;
接口的实现类可以不抛异常,也可以抛出与接口不一样的异常. 但是必须是接口定义的异常或是该异常的子类;
StormyInning
不仅继承了Inning
,也实现了Storm
接口,Inning
中的event()
方法声明抛出的异常是BaseballException
,Storm
接口中的event()
方法声明抛出的异常为RainedOut
,如果你只是继承了Inning
,那么抛出BaseballException
异常是没问题的,但是StormyInning
还实现了Storm
接口,那抛出BaseballException
异常就不行了
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。