是否可以使用IllegalStateException捕获所有子异常?

时间:2011-05-23 03:24:51

标签: java api exception

我想知道在这种情况下使用IllegalStateException是否是API的一个很好的设计选择。

方案: 我有一个函数,它检查XML文档是否格式良好,具有以下签名:

public boolean isXMLDocumentWellFormed(InputStream inXMLDocument)

此函数使用以下代码段加载XML文档:

    boolean isXMLDocWellFormed = false;

    // Setup document builder
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
            .newInstance();

    if (docBuilderFactory == null)
        throw new IllegalStateException(
                "The DocumentBuilderFactory cannot be instanciated");
    try {
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

        // Parse document
        Document doc = docBuilder.parse(inXMLDocument);

        if (doc != null)
            isXMLDocWellFormed = true;

    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    }

    return isXMLDocWellFormed;

API的设计非常易于使用。但是,我想向API用户提供了解无法检查XML文档的原因(例如:DocumentBuilderFactory无法创建DocumentBuilder)对象)没有用他们必须处理的大量检查异常压倒他们。

我对此设计的担忧是:

a)使用一个单独的Exception类型(即IllegalStateException)来返回每个可能捕获的异常以指示无法执行检查是个好主意吗?我会说是,因为用户除了2件事情超出这个功能:

  1. 了解XML文档是否格式正确。
  2. 要知道函数无法返回答案(例如由于异常),为什么函数无法提供答案。
  3. b)如果a)的答案为否,那么什么是最合适的例外名称或解决方案以及为什么

    此致

3 个答案:

答案 0 :(得分:2)

我对人们的第一个建议就是不要仅仅为了有效地重新抛出异常。当你真正可以对它们做些什么时捕获。所以考虑一下。但是在您捕获已检查异常并将其包装在运行时异常中的示例中,我会问一个问题 - 这种情况会发生多久?如果异常可能是常见的(或严重的),那么您希望程序员确保他们处理它们,因此检查是要走的路。但是,如果它们不常见(并且不严重),那么抛出包装运行时可能是可以接受的。这是你需要考虑的事情,因为没有什么能比开发人员更多地惹恼开发人员。

说完所有这些:-)如果你打算换行我会考虑创建你自己的异常,因为你想清楚它是你的而不是Java的。您甚至可以使用扩展运行时的通用异常创建层次结构,然后使用扩展您的通用异常的更具体的层次结构。因此允许API用户选择在不同级别捕获。

答案 1 :(得分:0)

如果它是您开发的API,那么您应该将所有异常包装在一个主要异常中。这样您就不会泄露实现细节。但是你的个人品味可能会有所不同

但是我认为IllegalStateException并不适合这里。它非常通用,并没有解释问题(一个IO异常是非法状态?)。最好的解决方案是创建自己的自定义Exception类并抛出它。

作为您或其他任何人的副节点,请不要在抛出异常时打印异常。

答案 2 :(得分:0)

我建议,例行程序泄漏四种类型的异常可能是最有帮助的:

  1. CleanFailureException:请求的操作失败,但尝试没有任何副作用。抛出异常的实体应该从它自己的角度处于有效状态,尽管它可能不符合该类用户可能期望的某些不变量。示例:从Dictionary中检索不存在的键。 Dictionary的数据结构可能完全有效,作为Dictionary,但是应用程序可能期望它处于包含所请求键的状态(也可能是Dictionary处于正确状态,而其他东西给应用程序提供了错误的键)。
  2. PartialOperationException:请求的操作未完成,但可能已完成到某种程度未知。如上所述,抛出异常的实体可能从其自身的角度处于有效状态,但调用者必须检查它是否处于调用者认为有效的状态。
  3. StateCorruptException:请求的操作未完成,尝试它的对象或某个嵌套对象似乎具有损坏状态。
  4. SystemOnFireException:系统中任何事物和所有内容的状态都应被视为可疑。

由超出范围的数组索引引起的异常可能属于上述任何类别。重要的不是访问了一个越界索引,而是它对其他对象意味着什么。 Catch,wrap和rethrow将是一个非常有用的模式,因为将异常解析为上述类别之一将使调用者更好地了解如何处理它。