什么时候应该检查异常/未选中的异常?

时间:2012-03-30 17:19:39

标签: java exception compiler-construction coding-style checked

我从各种教程中了解到“如果可以合理地期望客户端从异常中恢复,请将其作为已检查的异常。如果客户端无法执行任何操作以从异常中恢复,请将其设置为未经检查的异常。”

我真的希望通过一些代码示例看到之前语句的有效性。 例如

try {
        br.readLine();
    } catch (IOException e) {

        e.printStackTrace();
    }

这里,IOException被检查Exception.So,当这个异常发生时,我应该如何恢复?在这里,我排除异常记录,异常重新抛出任务,因为它们实际上并没有恢复,即正确的事情。那么,应该采用什么修改来从中恢复呢?

如果有办法从中恢复,那么同样的方法可以应用于以下代码:

 try{
    Integer.parseInt("ghg4");
 }catch(NumberFormatException nfe){   
   }

这里的NumberFormatException是一个运行时/未经检查的异常。如果有办法从中恢复,那么为什么它首先被声明为运行时异常?

3 个答案:

答案 0 :(得分:1)

c#消除了检查异常,我认为这是一个好主意。

在我编写的代码中,我主要遵循c#模式,从RuntimeException扩展所有内容。然而,在某些地方,我利用已检查的例外情况迫使自己和使用我的代码的任何人回应更多的“正常”异常情况

答案 1 :(得分:1)

RuntimeException和Exception之间没有明确的边界。一般来说,过度使用Exception的后代导致catch子句链(例如反射处理代码)或仅catch (Exception e)不关心特定类型。有许多不同的做法,这个问题是有争议的 - 即它并不那么简单,并且没有唯一一种正确的方法来设计应用程序中的异常。


我遵守以下规则:

  1. 如果异常将单独处理,并且可以与简单的输入数据错误或类似错误区分开来 - 这是一个经过检查的异常。

  2. 如果异常是由明显错误的输入条件或代码中的错误(如NPE)引起的 - 那么它就是运行时异常。

  3. 从这个逻辑来看,例如,我会将IOException作为RuntimeException的后代。


    更新:关于IOException,这不是黑白分明的。但是一些IOE后代(如FileNotFoundException,MalformedURLException等) - 肯定只是糟糕的输入。当你使用ByteArray IO Streams(或类似的)来处理从未发生的IOE时,它会让事情变得烦人。

答案 2 :(得分:1)

我看到三种类型的例外。在一个极端是您无法做任何事情,如NullPointerException。您将在代码中以非常高的级别处理此问题,或者根本不处理。检查它是荒谬的。

另一端是那些提供有意义信息的人。当方法已经具有返回值时,它们有点返回值,有时是复数值。它们也是一种跳跃调用堆栈的简单方法。 (我可以写一本关于这个的书,但我会在这里停下来。)EOFException 应该就是一个很好的例子。文件有它们的目的,你迟早会打它,并且你不想每次阅读都要检查它。在这种情况下,将调用已检查的异常。 (我认为user1291492会就此与我达成一致。)它可能会发生,任何调用read方法的人都应该为此做好准备。他们更喜欢编译器错误和运行时错误。

现在有这种类型的异常,你想要放入堆栈跟踪!这需要很多时间。调用者只需知道他打了一个EOF,而不是发生在IO系统的深处!此外,除非要返回有趣的信息,否则异常本身应该是final static引用,生成一次并用于发生的每个EOF。

中间的第三种类型是Java库使用的类型,如 real EOFException。他们毫无意义。要么调用者不希望得到EOF(例如他把自己的标记放在那里),EOFException与NullPointerException具有相同的性质,他期望它并且不需要麻烦并且丢失了堆栈跟踪的处理时间。我认为问题在于Java设计者本身 - 而且我不得不承认在我考虑这个问题时自己也有这个问题 - 这很少 - 不确定这两个类别中的哪两个可能属于这些例外。即使在同一个程序中,在一个地方,EOFException也可能表示程序完全失败。在另一种情况下,可能是找出文件已被读取的常规方法。因此,最终结果是大量例外,这两个例子同时完成这两项工作并且做得很差,迫使程序员在他们无法做任何事情时使用trycatch以及throws并处理他们精心制作了他们不需要的堆栈痕迹。

添加:我应该明确指出,您可以通过简单地接受已经完成阅读文件并继续执行,可能在真正的EOFException中恢复,可能使用break语句catch阻止。但是,还有其他正确的方法来捕获EOF,因此EOFException通常意味着像NullPointerException这样的真正问题。奇怪的是,我使用NumberFormatException的方式,我认为应该进行检查。当我想要一个数字时获得“AAA”是非常常见的,用户错误,而不是编程错误。