很难理解检查和;未经检查的例外情况

时间:2012-11-11 17:04:58

标签: java exception exception-handling checked-exceptions unchecked-exception

我已经阅读了关于此的所有内容,但我仍然不明白如何使用已检查和未检查的异常。我想我还是不能理解这个概念。我已经阅读了StackOverflow,它是更好使用未经检查而不是检查异常,但Eclipse 强制我使用已检查的异常,如FileNotFoundException(AFAIK,如果Eclipse强制我插入try / catch块,那么它是一个经过检查的异常)。我想知道,有没有办法将翻译签入未选中状态?到底是什么处理本身?我不明白处理异常是什么。

我在这里有这个例子,我真的想知道如何处理(?)这个。这是一个经过检查的例外,对吧?

public void readFile() {
    File foo = new File("./foo.bar");
    try {
        BufferedReader bufferedReader = new BufferedReader(new FileReader(foo));
    } catch (FileNotFoundException e) {
        // What should I do here?
    }
    getDataFromFile(bufferedReader);
}

我见过人们在这里做的各种事情。有些人会打印堆栈跟踪,这就是我通常所做的,而且我没有看到它的问题。它为我提供了调试所需的信息。有些人会忽略它们,我认为不应该这样做(我看到JNode OS引导程序忽略了异常)。有些人只是在签名中添加throws声明。有些人会在那件事中抛出更多异常! (我想也许这就是使用unchecked而不是checked方法?)

此外,如果你添加throws声明,你将被迫进一步放置一个try / catch块,如果你有一个非常大的应用程序,这是不方便的。对不起,我只是一无所知。完全。我正在努力学习优雅而优雅的设计,这让我感到折磨。

4 个答案:

答案 0 :(得分:6)

未选中的例外

是一个例外,因为首先不应该发生这种情况,因此无法预料。它处理的案例只有在您的程序有错误时才会出现

它是RuntimeException的子类(Exception的子类),通常使用IllegalArgumentExceptionNullPointerExceptionIllegalStateException <来实现/ p>

  

未经检查的运行时异常通常表示条件   说,反映程序逻辑中的错误,不能   从运行时间合理地恢复。


已检查异常

由于系统其他部分存在不可预见的情况,

可能会发生。它超出了您的直接控制范围,但不一定是错误,但可能会遇到案例

它是Exception

的子类

<强> From: Exceptions


在您的示例中,

如果某些条件占优势(磁盘已满),即使在生产代码中,您也需要处理该文件,因为它可能会发生。这使它成为一个经过检查的例外。


处理异常:

  

例外旨在提供更好的用户体验。所以   您应该将错误报告给用户,并优雅地终止if   你不能继续。

  1. 如果确实是您预料到的情况,那么您应该告知用户该问题,并在必要时优雅地终止,或继续进行下一步。

  2. 如果它是一个未经检查的异常,你可以做的最好的事情是告诉用户而不是发生意外错误,因为它不是首先发生的事情,并将堆栈跟踪报告回你。

答案 1 :(得分:1)

首先,例外是​​你的朋友:) - 不,真的。例外是一种非常强大且安全的错误处理方式。

基本上,Java中已检查和未检查的异常之间的区别是对异常的预期反应:

经过检查的异常通常用于将某种操作的“意外”结果传达给调用者,调用者被认为是要明确处理该异常状态。

未经检查的异常通常是被认为或多或少无法恢复的异常。它用于指示一些假设使整个操作无效的故障情况。与NullPointerException一样,这些例外在几乎所有操作中或多或少都是潜在的。对它们进行检查意味着调用者需要在错误处理中产生一些令人讨厌的开销。

在你的例子中,你可能会这样:

public void readFile() {
    File foo = new File("./foo.bar");
    try {
        BufferedReader bufferedReader = new BufferedReader(new FileReader(foo));
        getDataFromFile(bufferedReader);  // If the file could not be found above, this will never execute!
    } catch (IOException e) {
        // React, e.g.:
        System.out.println("Data could not be read due to an IO error.");
    }

}

重新抛出异常或将一个异常包装在另一个异常中并不罕见。 - 例如,当IOException发生攻击时,您可能需要进行一些清理,关闭一些打开的文件等,然后按原样处理异常或修改为调用者,以便他可以处理异常。适当的方式。

您实际处理特定异常的方式完全取决于您。根据用户(例如您自己)和运行代码打印的环境,堆栈跟踪可能没问题。或者,也许,您想在暂停一段时间后重试刚刚做的事情。或者,在给出的示例中,您可以向用户显示消息并要求他重新输入文件名,&amp; c。

后者是可以有效使用不同类别的异常的方式:FileNotFoundExceptionIOException的子类)可以通过用户交互来恢复;裸IOException可能被认为是不可恢复的,因为在最坏的情况下甚至可能表示某种硬件故障。

答案 2 :(得分:1)

让我们以你的例子(修改)本身来解释。

public void readFile() {
    BufferedReader bufferedReader = null;
    try {
            File foo = new File("./foo.bar");
        bufferedReader = new BufferedReader(new FileReader(foo));
    } catch (FileNotFoundException e) {
        // What should I do here?
    }
    getDataFromFile(bufferedReader);
}

当您获得FileNotFoundException异常时,您的bufferedReader不会使用文件流进行初始化。在这种情况下,您的下一个语句getDataFromFile(bufferedReader);将失败,因为没有bufferedReader来读取数据。

因此,在catch块中,您可以执行以下两项操作:

  1. 抛出新的自定义异常并从程序返回
  2. 尝试更正再次获取文件句柄的问题(在这种情况下,一个示例可能是使用默认文件),因此bufferedReader已正确初始化。
  3. 这样,CheckedException在编写程序本身时很有用。它们为您提供有关可能故障的输入,使您能够提前做出适当的处理决策。

    另一方面,未编辑的异常(如NullPointerException)在编译时很难识别,可能会被忽视。如果发生但未处理,则会在运行时导致问题。

答案 3 :(得分:1)

检查异常是屁股的痛苦。

很抱歉使用这种直言不讳的语言,但它们是Java最糟糕的设计错误之一!如果您必须处理仍使用已检查异常的旧API,例如Eclipse或Java自己的API,我个人所做的就是将它们包装到我自己的未经检查的异常中。最好使用自己的标记类。这有助于您将这些异常识别为由代码引起的,例如在日志文件中或调试时。

我个人非常满意地调用我的标记类BullshitFree所以我可以重新抛出已检查的异常,如下所示

try {
    // call to legacy API that still uses checked exceptions
} catch(CheckedException exception) {
    throw new BullshitFree(exception);
}

确保您的BullshitFree异常类实际延伸RuntimeException,以便取消选中!

对于您的代码示例,有两个选项。如果有办法从中恢复,例如通过创建文件或将错误报告给用户,请执行此操作。如果没有,或者它只是一个你自己使用的小脚本,请将其包装在BullshitFree例外中,并在剩下的时间里学习Ruby或其他精心设计的语言......

您的milage可能会有所不同。