技巧:当不能抛出异常时 - 编程入门网
技巧:当不能抛出异常时时间:2012-01-28 IBM Elliotte Rusty Haroldchecked 异常的一个问题是,有时候不允许抛出这样的异常。特别是,如果要覆盖超类中声明的方法,或者实现接口中声明的方法,而那个方法没有声明任何 checked 异常,那么新的实现也不能声明 checked 异常。因此必须预先处理异常。另外,可以将异常转换为运行时异常,或者绕过它而不处理它。但是,应该这样做吗,这其中是否隐藏着错误? 问题 只要看一个例子,问题就清楚了。假设有一个 File 对象的 List,需要按它们的标准路径以字典顺序排序。所谓标准路径,是指在解析别名、符号链接和 /../ 及 /./ 之后得到的完整绝对路径。本地方法使用一个比较器,如清单 1 所示: 清单 1. 按标准路径比较两个文件
不幸的是,该代码不能通过编译。问题在于,getCanonicalPath() 方法抛出一个 IOException,因为它需要访问文件系统。通常,当使用 checked 异常时,可以使用以下两种方法之一: 将出错的代码包装在一个 try 块中,并捕捉抛出的异常。 声明包装方法(本例为 compare())也抛出 IOException。 通常,至于选择何种方法,取决于是否能在抛出异常时合理地处理异常。如果能,那么使用 try-catch 块。如果不能,那么声明包装方法本身抛出异常。不幸的是,这两种技巧对于本例都不管用。 在 compare() 方法中无法合理地处理 IOException。从技术上讲,似乎可以做到 — 即返回 0、1 或 -1,如清单 2 所示: 技巧:当不能抛出异常时(2)时间:2012-01-28 IBM Elliotte Rusty Harold清单 2. 抛出异常时返回一个默认值
然而,这违反了 compare() 方法的约定,因为它不是一个稳定的结果。对于相同的对象,前后两次调用可能产生不同的结果。如果使用这个比较器来排序,那么意味着最终列表没有被正确排序。所以现在试试第 2 个选项 — 声明 compare() 抛出 IOException:
这也不能通过编译。因为 checked 异常是方法签名的一部分,在覆盖方法时,不能增加 checked 异常,就像不能改变 return 类型一样。那么最后还剩下一个折中选项:在 compare() 中捕捉异常,将它转换成运行时异常,然后抛出运行时异常,如清单 3 所示: 清单 3. 将 checked 异常转换成运行时异常
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |