快速业务通道

技巧:当不能抛出异常时 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-13

技巧:当不能抛出异常时

时间:2012-01-28 IBM Elliotte Rusty Harold

checked 异常的一个问题是,有时候不允许抛出这样的异常。特别是,如果要覆盖超类中声明的方法,或者实现接口中声明的方法,而那个方法没有声明任何 checked 异常,那么新的实现也不能声明 checked 异常。因此必须预先处理异常。另外,可以将异常转换为运行时异常,或者绕过它而不处理它。但是,应该这样做吗,这其中是否隐藏着错误?

问题

只要看一个例子,问题就清楚了。假设有一个 File 对象的 List,需要按它们的标准路径以字典顺序排序。所谓标准路径,是指在解析别名、符号链接和 /../ 及 /./ 之后得到的完整绝对路径。本地方法使用一个比较器,如清单 1 所示:

清单 1. 按标准路径比较两个文件

import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class FileComparator implements Comparator<File> {    public int compare(File f1, File f2) {      return f1.getCanonicalPath().compareTo(f2.getCanonicalPath());    }    public static void main(String[] args) {     ArrayList<File> files = new ArrayList<File>();     for (String arg : args) {       files.add(new File(arg));     }     Collections.sort(files, new FileComparator());     for (File f : files) {       System.out.println(f);     }    } }

不幸的是,该代码不能通过编译。问题在于,getCanonicalPath() 方法抛出一个 IOException,因为它需要访问文件系统。通常,当使用 checked 异常时,可以使用以下两种方法之一:

将出错的代码包装在一个 try 块中,并捕捉抛出的异常。

声明包装方法(本例为 compare())也抛出 IOException。

通常,至于选择何种方法,取决于是否能在抛出异常时合理地处理异常。如果能,那么使用 try-catch 块。如果不能,那么声明包装方法本身抛出异常。不幸的是,这两种技巧对于本例都不管用。

在 compare() 方法中无法合理地处理 IOException。从技术上讲,似乎可以做到 — 即返回 0、1 或 -1,如清单 2 所示:

技巧:当不能抛出异常时(2)

时间:2012-01-28 IBM Elliotte Rusty Harold

清单 2. 抛出异常时返回一个默认值

public int compare(File f1, File f2) {    try {      return f1.getCanonicalPath().compareTo(f2.getCanonicalPath());    }    catch (IOException ex) {      return -1;    } }

然而,这违反了 compare() 方法的约定,因为它不是一个稳定的结果。对于相同的对象,前后两次调用可能产生不同的结果。如果使用这个比较器来排序,那么意味着最终列表没有被正确排序。所以现在试试第 2 个选项 — 声明 compare() 抛出 IOException:

public int compare(File f1, File f2) throws IOException {    return f1.getCanonicalPath().compareTo(f2.getCanonicalPath()); }

这也不能通过编译。因为 checked 异常是方法签名的一部分,在覆盖方法时,不能增加 checked 异常,就像不能改变 return 类型一样。那么最后还剩下一个折中选项:在 compare() 中捕捉异常,将它转换成运行时异常,然后抛出运行时异常,如清单 3 所示:

清单 3. 将 checked 异常转换成运行时异常

public int compare(File f1, File f2) {    try {      return f1.getCanonicalPath().compareTo(f2.getCanonicalPath());    }    catch

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号