繁体   English   中英

在Java中处理几个异常

[英]Handling several exceptions in Java

请考虑以下Java代码:

try{

    // do something
    // this piece of code throws several checked exceptions.

} catch (IllegalArgumentException e) {
    handleException(e);
} catch (IllegalAccessException e) {
    handleException(e);
} catch (InvocationTargetException e) {
    handleException(e);
} catch (InstantiationException e) {
    handleException(e);
} catch (NoSuchMethodException e) {
    handleException(e);
} catch (IOException e) {
    handleException(e);
} catch (NoSuchFieldException e) {
    handleException(e);
}

try块中的代码会抛出几个已检查的异常。 我想要做的就是在发生异常时记录消息(带有一些自定义消息字符串)。 即我的异常处理逻辑对于所有异常都是相同的。

我觉得上面的代码看起来不太好(更多LOC和可读性降低)。

有没有更好的办法处理此类案件?

以下解决方案不是最佳实践,因此不推荐(通过检查样式)。

try{
    // do something very bad
} catch (Exception e) {
    handleException(e);
} 

在Java 6中,您没有比您已经建议的更具吸引力的选项。

但是Java 7有一个可以使用的多捕获语句:

catch(IllegalArgumentException | IllegalAccessException | IOException exception) {
    handleException(e);
}

我觉得在你的情况下,第二个选项会做得很好。 如果异常处理对于每种情况都相同,则无需使代码过度复杂化。

在Java 7中,有一个新的优秀解决方案:您可以编写:

try{

    // do something
    // this piece of code throws several checked exceptions.

} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
    handleException(e);
} catch ...

在较旧的Java版本中,捕获公共子类 - Exception情况就是这种情况 - 实际上并不是一个坏主意。 总是在没有考虑的情况下做到这一点很糟糕,但如果您已经考虑过它并将其选为最佳解决方案,那么可以这样做。

Java 6或更低版本没有任何关系。

使用java 7,您可以执行以下操作:

catch(InstantiationException | IOException | NoSuchFieldException exception) {
        // handle our problems here.
}

在java 6中,另一个“糟糕的做法”(但可能对你有用)可以是:

catch (Exception e) {
   if(! e instanceof RuntimeException) // Only non-checked exceptions!
       throw e;
   handleException(e) // All checked exception.
}

问题:您正在使用instanceof。 但是你的代码看起来更好......

这是检查异常如何使Java程序员的生活变得悲惨的另一个例子。 仅仅因为一段代码可以抛出已检查的异常,特定的代码片段很可能不是您想要处理它们的地方。 如果您的应用程序设计得很好,那么您已经拥有了一个中心位置,一个异常屏障 ,您可以处理(记录)异常。 如果是这种情况,那么您应该将所有这些异常包装到RuntimeException并将它们传递给屏障。 在这种情况下,这是处理代码:

try {
  // do stuff
} catch (RuntimeException e) { 
  throw e; 
} catch (Exception e) { 
  throw new RuntimeException(e); 
}

你们对这个解决方案有什么看法?

try {
    // some code that might throw an exception.
} catch (Exception e) {
    if(e instanceof RuntimeException){
        throw (RuntimeException) e;
    }
    // log exception
}

优点:

  1. 较少的代码可以为所有已检查的异常保留相同的异常处理逻辑。
  2. 不处理运行时异常和错误。 抓住他们但扔回去。

缺点:

  1. 不要确认最佳实践检查,因为它仍然捕获异常。 (但是检查运行时异常的情况很谨慎,但检查样式可能会失败。)
  2. 向下转换为RuntimeException的任何可能的副作用?

看起来Java 7团队中的人听到了你的抱怨:-) http://www.oracle.com/technetwork/articles/java/java7exceptions-486908.html

您的代码看起来像是要执行此操作:

try{
    // do something very bad
} catch (Throwable e) {
    handleException(e);
}

这不仅会捕获所有异常,还会捕获错误 - 可能会在try / catch块中抛出的所有异常。

捕获所有异常并让所有错误都通过很少是正确的事情,但是抓住一长串任意选择的无关异常甚至不太可能做正确的事情。

您的例外列表看起来很可疑。 也就是说,为什么会捕获IllegalArgumentException但不会捕获NullPointerException或ClassCastException,它们在语义上处于类似的级别。 而且您似乎将Reflection与IO结合使用,因此您可能还必须处理NoClassDefFoundError,ExceptionInInitializerError和其他错误。 那么StackOverflowError甚至是OutOfMemoryError ......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM