当前位置: 首页 > 面试题库 >

我该如何以安全且可读的方式处理一个我永远不会抛出的IOException?

吕自怡
2023-03-14
问题内容

“可能出错的事情和不可能出错的事情之间的主要区别是,当一件不可能出错的事情出错时,通常发现根本无法修理。” -道格拉斯·亚当斯

我有一类FileItems。FileItems构造函数获取一个文件,如果该文件不存在,则抛出异常(FileNotFoundException)。该类的其他方法也涉及文件操作,因此可以抛出FileNotFoundException。我想找到一个更好的解决方案。一种不需要其他程序员处理所有这些极不可能的FileNotFoundExceptions的解决方案。

问题事实:

  1. 已检查文件存在,但极有可能的情况是,由于现实的一些重大缺陷,可能在调用此方法之前删除了文件。
  2. 由于1发生的可能性极不相同且无法恢复,因此我希望定义一个未经检查的异常。
  3. 已经发现该文件存在,从而迫使其他程序员编写代码并捕获检查到的FileNotFoundException看起来乏味且无用。该程序此时应该完全失败。例如,总是有机会使计算机着火,但是没有人会疯狂地强迫其他程序员将其作为受检查的异常来处理。
  4. 我不时遇到这种Exception问题,每次遇到此问题(我的旧解决方案)时都定义自定义未经检查的异常(我的旧解决方案)很累,并且增加了代码膨胀。

目前的代码如下所示

 public Iterator getFileItemsIterator() {
    try{
        Scanner sc = new Scanner(this.fileWhichIsKnowToExist);
        return new specialFileItemsIterator(sc);        
       } catch (FileNotFoundException e){ //can never happen}

    return null;
 }

如何在不定义自定义未经检查的FileNotFoundException的情况下更好地做到这一点?有什么方法可以将checkedException强制转换为uncheckException吗?


问题答案:

处理此问题的通常模式是异常链接。您只需将FileNotFoundException包装在RuntimeException中:

catch(FileNotFoundException e) {
    throw new RuntimeException(e);
}

此模式不仅适用于在特定情况下(例如您的情况)无法发生异常的情况,而且适用于您无意或无意真正处理该异常的情况(例如数据库链接失败)。

编辑 :提防这种外观相似的反模式,我在野外经常看到的情况:

catch(FileNotFoundException e) {
    throw new RuntimeException(e.getMessage());
}

这样,您就丢弃了原始堆栈跟踪中的所有重要信息,这通常会使问题难以跟踪。

另一个编辑: 正如ThorbjørnRavn
Andersen在他的答复中正确指出的那样,在注释中,或者甚至更好地,将异常链接到异常消息中来说明为什么要链接异常:

catch(FileNotFoundException e) {
    throw new RuntimeException(
        "This should never happen, I know this file exists", e);
}


 类似资料:
  • 问题内容: 几天前,我意识到PrintWriter(以及PrintStream)在写入,刷新或关闭时 从不会抛出IOException 。 而是在发生错误时设置内部标志()。 不可能获得确切的异常,只有 在 存在某些异常(checkError())的情况下。 我的问题是:为什么一个人要发生这种行为?API设计不是很糟糕吗? 问题答案: 我认为由于是和的实例,因此提供了一些更轻松的错误处理。就像其他

  • 遵循Joshua Bloch的《有效的Java》中使用的风格,并与这个问题的答案一致,我过去在Java SE环境中使用AssertionErrors来表示不应该执行的代码路径。 看看JavaEE,EJB3.1规范说 如果bean方法遇到系统异常或错误,它应该简单地将错误从bean方法传播到容器(即,bean方法不必捕获异常)。 再往下一点,它说在非应用程序异常的情况下必须丢弃相关的EJB实例。据我

  • 我正在学习Java8以及更多关于“可完成的未来”的细节。以下是有趣的教程:https://www.callicoder.com/java-8-completablefuture-tutorial/ 我编写了以下Java类: (为了运行该代码,您需要resteasy-Client库) 但是我不明白为什么即使收集了所有的响应,主方法也不会终止... 我错过什么了吗?是否有一些“完整”的方法可以在任何地

  • 虽然已经在响应拦截器里做了一些全局处理,最后是通过 Promise.reject 抛出的异常 现在每个接口请求方法都还是得写 try/catch 或者 .catch() 真的好麻烦 有什么比较好的方案吗?

  • 问题内容: 我想了解如何使用dis(Python字节码的反汇编程序)。具体来说,应该如何解释(或)的输出? 。 这是一个非常具体的示例(在Python 2.7.3中): 我看到等是字节码指令 (尽管有趣的是,它没有出现在此列表中,尽管我希望它可以作为)。我认为右侧的数字是内存分配,而左侧的数字是goto数字…我注意到它们每次 几乎 增加3(但不是完全一样)。 如果我包装一个函数: 问题答案: 您正

  • 我想知道为什么java编译器允许在方法声明中抛出,而方法永远不会抛出异常。因为“throws”是处理异常的一种方式(告诉调用方处理它)。 因为有两种处理异常的方法(抛出和try/catch)。在try/catch中,它不允许捕获try块中未抛出的异常,但它允许在不抛出异常的方法中抛出。