1. 异常是方法执行完后才抛出的,跟返回结果相似,从这个角度来说不应该是方法签名的一部分。我们知道,如果根据不同的返回类型来区别签名从而达到重载的目的是不允许的,因为方法在没有返回前系统是不知道该选择哪个方法来执行的。Java中也不允许仅仅异常声明不一样的方法进行重载。
2. 异常在接口实现,方法继承中只能变的越来越少(变窄)。也即父类异常声明必须包括(或者说是子类异常的父类)子类异常声明。这个可以这么理解,因为我们都是面向接口或者超类编程,客户端代码一定捕获的是接口或者超类中声明的异常。这样不管具体实现类中抛出什么样的异常,对客户端代码中的try,catch结构不会有任何影响。相反如果具体类中抛出一个接口中没有的异常,客户端的代码(catch语句)就要必须做出改变,这也就破坏了我们面向接口编程的初衷了。而Core Java中异常的处理正是按照继承或接口实现时异常变窄来实现的。
3. 针对实现接口时方法声明中异常变窄的性质。RMI和EJB中有一个设计的模式可以参考。
我们知道,RMI中需要声明一个远程接口,每个暴露出来的方法需要抛出java.rmi.RemoteException,远程接口需要继承java.rmi.Remote接口。对于客户端调用来说对于这么RemoteException基本上是无能为力的,相反写起代码起来比较麻烦。一种思路是对应远程接口声明一个业务接口,该业务接口中不包括Remote,RemoteException声明。服务端RMI实现时一个改变是需要同时实现远程接口和业务接口。对于客户端来说跟以前一样,只是根据Naming找到对象以后转化为业务接口操作即可。当然如果需要处理RemoteException的话那么把取出来的对象转化为远程接口接口即可。