【问题标题】:Should I catch checked exception intentionally?我应该故意捕获检查的异常吗?
【发布时间】:2011-05-26 20:58:03
【问题描述】:

我设计了一个上传文件的处理方式如下:

UploadFileHandler 是提供检查方法的主要类。

public class UploadedFileHandler {

    public static void handleUploadedFile(String fileName) {
        try {
            checkFile(fileName);
        } catch (BadUploadedFileException ex) {
            deleteFile(fileName);
        }
    }

    private static void checkFile(String fileName) {
        new UploadedFileChecker(fileName).check();
    }

    private static void deleteFile(String fileName) {
        //...code to delete the file.
    }
}

UploadedFileChecker 进行检查。

public class UploadedFileChecker {
    private String fileName;

    public UploadedFileChecker(String fileName) {
        this.fileName = fileName;
    }

    public void check() throws BadUploadedFileException {
        checkFileFormat();
        scanVirus();
    }

    private void checkFileFormat() {
       // if file format unsupported
       throw new BadUploadedFileException();
    }

    private void scanVirus() {
        // if contains virus
        throw new BadUploadedFileException();
    }
}

BadUploadedFileException 声明如下:

public class BadUploadedFileException extends RuntimException {

}

我让它扩展 RuntimeException,因为它使 UploadedFileChecker 中的代码干净,但这样做会使其成为未经检查的异常。因此,handleUploadedFile 中的捕获是不合适的,因为我们不应该捕获未经检查的异常。

我的问题是,我应该捕获 BadUploadedFileException 还是让它扩展 Exception 并将“throws BadUploadedFileException”附加到 UploadedFileChecker 的每个方法中。

【问题讨论】:

    标签: java exception


    【解决方案1】:

    异常应该用于异常条件。你不希望发生的事情。

    您不应该将它们用于条件逻辑。

    Josh Bloch 在他的书中特别概述了这一点,这非常好,恕我直言:

    http://java.sun.com/docs/books/effective/

    【讨论】:

    • 同意,这是正确的。如果可以使用条件逻辑来避免异常,那就去做吧。 void checkFileFormat 应该是 boolean isValidFormat()void scanVirus() 应该是 boolean hasVirus()。如果可以的话,因为它是一个处理程序,所以在构造时自动执行这些操作,然后只给用户这些已经评估过的东西。
    • 谢谢克里斯——完美的例子。
    【解决方案2】:
    since we should not catch unchecked exceptions.
    

    没有这样的规则。只要您知道如何处理异常,就可以捕获任何异常。

    但是,绝对不能捕获错误!

    【讨论】:

      【解决方案3】:

      我认为你最好让 check() 返回一个布尔值。
      我相信这会让代码看起来更干净,就像 Brian 所说的那样——异常并不是真正的逻辑——它们是用于出现意外错误的时候。

      【讨论】:

        【解决方案4】:

        如果遇到异常,你会做些什么吗?如果没有,让它冒泡。如果你是,那么你当然可以捕获一个未检查的异常。

        【讨论】:

          【解决方案5】:

          个人认为应该是检查异常。你应该试探。从每个文件处理方法中抛出它并在 UploadedFileHandler 中捕获它,并对其进行适当处理,如果您需要不同的处理逻辑,则将 BadUploadedFileException 拆分为许多不同类型的异常。

          有关已检查和未检查异常的更多信息here

          【讨论】:

            【解决方案6】:

            最后一个选项会更好。我认为这不会使代码更难阅读,至少您(以及即将发布的版本中的同事)会记得处理它。

            除此之外,当然不禁止捕获从 RuntimeException 派生的异常。另一方面,捕获 RuntimeException 或 Exception 只能在 main 方法等中完成(它可能是 OutOfMemoryException!)。

            如果您使用显式 RuntimeExceptions,请不要在方法规范中使用“throws”关键字,但如果它们看起来很重要,请务必将它们包含在 JavaDoc 中。

            【讨论】:

            • 对我自己的答案添加评论:我认为 brian 是对的,这不是一个例外对于这个用例。当您明确检查格式和病毒时,如果您发现了也不例外。尽量避免抛出不必要的异常(如果只是为了让您在没有它们的情况下进行调试)。
            猜你喜欢
            • 2011-11-18
            • 2011-05-17
            • 2010-09-10
            • 1970-01-01
            • 2023-03-29
            • 1970-01-01
            • 1970-01-01
            • 2021-08-13
            相关资源
            最近更新 更多