使用内部检查异常抛出运行时异常是不好的做法吗?

时间:2015-08-06 16:37:42

标签: java exception

这是不好的做法吗?

public String foo(File file) {
    StringBuilder sb = new StringBuilder();
    try(
            BufferedInputStream bis =
                    new BufferedInputStream(
                            new FileInputStream(file))
    ) {
        for(int c = bis.read(); c != -1; c = bis.read())
            sb.append((char) c);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    return sb.toString();
}

假设没有办法优雅地从已检查的异常中恢复。

3 个答案:

答案 0 :(得分:5)

这并不理想,但有些情况下没有其他解决方法。

foo(File file)是接口方法的实现或超类方法的覆盖(未声明已检查的异常)时,此方法变得方便。这种情况会强制您在内部处理异常,或将其包装在未经检查的异常中。

然而,问题是RuntimeException的子类应该表示编程错误;另一方面,IOException not 表示编程错误,因此将其包装在RuntimeException中以绕过Java编译器的检查是错误的。

答案 1 :(得分:1)

Java运行时使用UncheckedIOException来处理这种情况。

我认为定义新类型的未经检查的异常并让它们从库中逃脱是一种不好的做法,因为它会导致漏洞抽象。如果要将已检查的异常重新抛出为未经检查的异常,请在核心Java运行时中找到合适的describe('Era', function() { it('Does era run?', function(done) { async.each(config.url.era, function(url, eachCb) { console.log('Opening connection to ' + url); request(url).get('/rest/status').expect(200).end(function(err, res) { console.log(err); if (err) return eachCb(err); // terminate the loop console.log('Time to assert some stuff'); assert.equal(res.text.indexOf('up') > -1, 'Node ' + url + ' failed with status ' + res.statusCode); eachCb(null); // continue with the next iteration }); }, done); // async.each() will call done() with err or null as argument }); }); 子类。

答案 2 :(得分:0)

检查异常是有问题的 - 我听说它们最好被描述为“失败的实验”。

未经检查的运行时异常是处理棘手情况的一种非常好的方法。例如,您经常会有一个大型高级线程,预计会运行“Forever”。该线程中可能有30个位置(在不同的方法中)从数据库读取或与其他不稳定的源交互。

如果该数据源失败,您总是希望以相同的方式处理它 - 重新连接然后重新启动主循环。

这在高级线程中很容易处理,但如果每个对象本身处理它,它会在整个项目中传播可怕的错误检查代码。

所以答案是,如果在那个级别没有任何有用的东西,请随意将已签入的运行时异常包装起来 - 并且我建议不要抛出一个已检查的异常,除非有一些东西是调用者必须立即处理(几乎从来不是这样 - 大多数问题都可以在更高的层次上处理)。

顺便说一句,我做了很多,几乎从不使用新的例外 - 你可以重用现有的例外,除非你有理由在更高层次上区分异常。