【问题标题】:Java exceptions and inner exceptions, am I doing this correctly?Java异常和内部异常,我这样做正确吗?
【发布时间】:2011-11-26 15:07:48
【问题描述】:

我正在根据 xsd 验证 xml,我发现在很多情况下必须处理异常。

我相信这些在 java 中被称为检查异常?

SchemaFactory sf = ....

Schema schema = sf.newSchema(...)    // SAXException has to be handled
Validator validator = ...

validator.validate(xmlFile);   // IOException has to be handled again

我应该如何编写这个代码块?

我是否使用嵌套在 try/catch 中的 try/catch?

【问题讨论】:

  • -1 12k 用户应该知道如何正确格式化他的问题。
  • +1 一个 12k 的用户刚接触 Java,但擅长其他专业领域。
  • @Osw:格式化问题不是 Java 的事情,而是 Stack Overflow 的事情。

标签: java xml exception checked-exceptions


【解决方案1】:
try {
  SchemaFactory sf = ....

  Schema schema = sf.newSchema(...)    // SAXException has to be handled
  Validator validator = ...

  validator.validate(xmlFile);   // IOException has to be handled again
} catch (SAXException e) {
    // handle SAX error
} catch (IOException e) {
    // handle IO error
}

【讨论】:

  • 非常感谢,作为一方,我应该在 finally 块中将 sf 和 schema 变量设置为 null 吗?
  • @Blankman,在你的情况下不需要使变量无效。这是一个与垃圾收集相关的好线程:stackoverflow.com/questions/850878/…
  • 在 Java 7 中,如果您想以相同的方式处理异常,可以使用 catch(SAXException | IOException e)。很多时候,您只是将异常重新包装在更高级别的异常中,而原来的异常是原因。在这种情况下,“MyMessageValidationFailedException”是合乎逻辑的。如果您想以不同的方式处理异常,请仅嵌套 try/catch,但如果代码变得过于混乱,您最好将方法分开。
【解决方案2】:

我是否使用嵌套在 try/catch 中的 try/catch?

国际海事组织,没有。

try {
    //...
} catch(SAXException e) {
    //handle SAXException
} catch(IOException e) {
    //handle IOException
}

我认为这样的代码看起来比嵌套的 try/catch 更简洁。

我应该如何编写这个代码块?

这取决于您是否需要在此处处理异常,在这种情况下您使用try/catch,或者如果需要调用者处理异常,在这种情况下您应该使用@987654323 将其传播给调用者@ 子句。

public void validateXml() throws SAXException, IOException {
    //...

【讨论】:

    【解决方案3】:

    实际上,如果您没有任何恢复策略,则不应该处理已检查的异常。

    您是否有其他架构以防您使用的架构引发 Sax 异常? 如果您使用的验证器引发 IO 异常,您是否有另一个验证器? 这些异常还有其他可能的恢复方式吗?

    如果不这样做,您可能应该将该异常包装在运行时(未经检查的)异常中,然后将其抛出到顶层(将被捕获的地方)。最后,如果需要了解问题,您可以在包装类中添加额外的消息。

    除非你的程序可以在没有这个 sax 模式的情况下正常工作(在这种情况下你会捕获异常,也能够捕获运行时异常),或者你的程序有恢复策略,否则你不应该在不重新抛出的情况下捕获异常它。

    如果你的恢复策略失败,你也可以将恢复异常包装成未经检查的异常,让顶层处理(log + error 500 或类似的东西)。

    这就是快速失败的原则。


    请注意,在 Java 中,多年来一直存在关于已检查与未检查异常的大争议。许多对 Java 有影响的人真的认为引入检查异常是一个错误。

    主要原因是:

    • 人们比较懒惰,往往会在错误的地方捕捉到异常,这样他们就不会再被打扰了。

    • 人们不遵循 sun 的建议:他们抛出已检查的异常只是为了在编译时为 API 的客户端“发出警告”。

    • 人们倾向于认为只有声明检查异常的方法才能引发异常,而任何代码/方法都可以引发异常。只有当编译器这样说时,您才应该捕获异常:您必须考虑在哪里适合捕获。

    有点同意布鲁斯·埃克尔的观点:

    我认为问题在于这是一个未经检验的假设 作为心理学领域的语言设计师。

    您可以找到许多关于该主题的链接。很多java开发者并没有意识到这一点,而且现在很多成熟的框架也主要使用unchecked exceptions(Spring、EJB3...)。

    此外,使用 C#(无检查异常)和 Java 的人倾向于认为没有检查异常会更好。

    所以你可以这样做:

    try {
        your code here
    } catch (Exception e) {
        throw new RuntimeException("optionnal message",e);
    }
    

    如果您认为它有用,您最终可以使用自定义运行时异常


    太阳来源:

    http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

    以下是底线准则:如果客户可以合理地 期望从异常中恢复,使其成为受检异常。如果 客户端无法从异常中恢复,使其成为 未经检查的异常。

    http://docs.oracle.com/javase/specs/jls/se5.0/html/exceptions.html#11.5

    异常类是所有异常的超类 普通程序不妨从中恢复。


    Bruce Eckel(《Java 思维》一书): http://www.mindview.net/Etc/Discussions/CheckedExceptions

    上一段中的“可忽略”是另一个问题。理论 是如果编译器强制程序员要么处理 异常或在异常规范中传递它,然后 程序员的注意力总会被带回到可能性上 错误,他们将因此妥善处理它们。我觉得 问题是这是我们所做的未经检验的假设 属于心理学领域的语言设计师。我的理论 是当有人试图做某事而你不断 用烦恼刺激他们,他们会使用最快的设备 可以让这些烦恼消失,这样他们就可以得到他们的东西 完成,也许假设他们稍后会回去取出设备。 我发现我已经在 Thinking in Java 的第一版中做到了这一点:

    ...
    } catch (SomeKindOfException e) {}
    

    【讨论】:

    • 所有这些文本,对于这个问题来说似乎有点太多了,然后接着捕获基本异常的实例。这对我来说肯定是-1,抱歉。在大多数图书馆等中,您不想捕获例如OutOfMemoryExceptions。
    • OutOfMemory 是错误,它们是 Throwables 但不是例外!因此捕获异常不会捕获错误!
    • 来自 Checkstyle:“理由:初级开发人员通常只是简单地捕获 Exception 以尝试处理多个异常类。不幸的是,这会导致代码无意中捕获 NPE、OutOfMemoryErrors 等”。看来我被错误的文档抓住了,我会尝试通知 checkstyle 团队。我将删除反对票,尽管我仍然不确定答案的有效性,或者这个问题的 catch(Exception e)。
    • 这并不是因为 checkstyle 说了些什么,这就是事实。自己思考并尝试告诉我为什么我们不应该捕获异常?为什么 checkstyle 会做出这样的规则? Checkstyle 可以捕获 Sax,然后 IO 然后 runtime,完全一样,在这种情况下,直接捕获 Exception :)
    • 其实我认为 checkstyle 只是想告诉初级开发人员他们不应该捕获运行时异常,因为(例外情况除外)它们应该在顶层处理,显示错误 500 或其他东西。但是如果你重新抛出它们,没有区别;)
    猜你喜欢
    • 1970-01-01
    • 2012-10-20
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 2011-04-04
    相关资源
    最近更新 更多