很难理解检查和未检查的异常



我已经阅读了有关此内容的所有内容,但我仍然不明白如何使用检查和未检查的例外。我想我仍然无法掌握这个概念。我已经阅读了stackoverflow,说使用未检查而不是检查的例外是更好的,但是Eclipse forces 我使用检查的异常,例如在FileNotFoundException中要插入尝试/捕获块,这是一个检查的例外)。我想知道,有什么办法可以翻译检查为未选中的检查吗?到底是什么本身。我不明白处理例外是什么。

我在这里有一个示例,我真的很想知道如何处理(?)。这是一个检查的例外,对吗?

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 Booter忽略了例外)。有些人只需在签名中添加throws声明即可。有些投掷更多的例外情况!(我认为也许这是使用未检查而不是检查的方法?)

此外,如果您添加throws声明,您将被迫进一步进行尝试/捕获块,如果您有很大的应用程序,那将是不便的。对不起,但我简直毫无头绪。完全地。我正在尝试学习良好而优雅的设计,这正在折磨我。

未选中的例外

是一个例外,因为首先不应该发生的事情,因此无法预料。仅当您的程序具有 bug 时,它才能处理出现的情况。

它是RuntimeException的子类(是Exception的子类),通常使用IllegalArgumentExceptionNullPointerExceptionIllegalStateException

实现

未检查的运行时例外情况表示通常 说话,反映您程序逻辑中的错误,不能是 在运行时合理地恢复。


检查了异常

由于系统的其余部分,

可能发生的事情可能发生。它不在您的直接控制之外,但是不一定是一个错误,而是可以遇到的情况。

它是Exception的子类。

来自:异常


在您的示例中,

不存在的文件是您需要处理的情况,即使在某些条件盛行(磁盘已满)的情况下,即使在生产代码中也可能发生。这使它成为一个例外。


处理例外:

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

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

  2. 如果这是一个不受限制的例外,那么您能做的最好的就是告诉用户,而不是出现意外错误,因为这不是首先要发生的事情,并且将stacktrace报告回到你。

首先,您的朋友是例外::) - 不,真的。例外是错误处理错误的强大且安全的方法。

基本上,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罢工时,您可能需要进行一些清理,关闭一些打开的文件或类似的内容,然后将异常AS交给呼叫者,以便他可以以适当的方式处理异常。<<<<<<<<<<<</p>

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

后者是可以有效使用不同类别异常的东西:FileNotFoundException(是IOException的子类)可以通过用户交互可恢复;裸露的IOException很可能被认为是无法恢复的,因为它在最坏的情况下甚至表明某种硬件故障。

让我们以示例(修改)本身要解释。

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已正确初始化。

以这种方式,CheckedException在编写程序本身时对情况有所帮助。他们为您提供有关可能失败的输入,并使您能够预先做出适当的处理决策。

另一方面,在编译时间很难识别未检查的例外,例如NullPointerException,并且可能没有注意到。如果发生并且没有处理,它们会在运行时间引起问题。

检查的异常是屁股的痛苦。

很抱歉使用这种钝语,但它们是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或其他设计精良的语言……

您的里程可能会有所不同。

相关内容

  • 没有找到相关文章

最新更新