《重构:改善既有代码的设计》
P65:Java之中还有一个特别关于「修改接口」的问题:在Throws子句中增加一个异常。这并不是对签名式(signature)的修改,所以你无法以delegation(委托手法)隐 藏它。但如果用户代码不做出相应修改,编译器不会让它通过。这个问题很难解决。你可以为这个函数选择一个新名字,让旧函数调用它,并将这个新增的checked exception(可控式异常〗转换成一个unchecked exception(不可控异常:)。你也可 以拋出一个unchecked异常,不过这样你就会失去检验能力。如果你那么做,你可以警告调用者:这个unchecked异常日后会变成一个checked异常。这样他们就有时间在自己的代码中加上对此异常的处理。出于这个原因,我总是喜欢为整个package定义一个superclass异常(就像java.sql的SQLException),并确保所有public函数只在自己的throws子句中声明这个异常。这样我就可以随心所欲地定义异常,不会影响调用者,因为调用者永远只知道那个更具一般性的superclass异常。
请问这段话是什么意思?
"
我用具体的代码来解释下吧
接口A,有方法X
public interface A { public void methodX() throws IOException; }
在用户模块有这样一段调用
public class ModuleUser{
public void methodY(A a) throws IOException
{
a.methodX();
}
}
现在要对方法X增加一个异常,变为:
public interface A {
public void methodX() throws IOException,DataFormatException;
}
这样用户模块ModuleUser的方法Y就要修改,不修改,编译就不会通过。
怎么样解决呢?
方法1,新方法调用旧方法。(接口中不能新方调用旧方法,所以我改为抽象类)
public abstract class A {
public void methodX() throws IOException
{
try {
methodNewX();
} catch (DataFormatException e) {
throw new RuntimeException(e);
}
}
public abstract void methodNewX() throws IOException ,DataFormatException;
}
方法2: 以拋出一个unchecked异常,unchecked就是编译器不检查的运行时异常。
如下
public interface A {
public void methodX() throws IOException,RuntimeException;
}
这样用户代码也不用改。
但这两个方法都不好。
作者喜欢的做法是这样的(也是推荐的方式)。
在包中定义自己的异常
public class MyException extends Exception {
}
接口一开始就写成
public interface A {
public void methodX() throws MyException;
}
用户模块就会是这样的:
public class ModuleUser{
public void methodY(A a) throws MyException
{
a.methodX();
}
}
如果再遇到上面要加异常信息的情况
就为MyException创建一个子类,加接口A上,这样用户代码就不用改,也能适配。
上面一段话大概就是想表达这个观点。
因为这本书是国外人写的,翻译成中文,所以读起来有点别扭。
英文原文是这样的
There is one particular area with problems in changing interfaces in Java: adding an exception to the throws clause.
读这本书,觉得不好理解的,就可试着看看英文原文。
"
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。