12

考虑以下 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 和降低的可读性)。

有没有更好的方法来处理这种情况?

以下解决方案不是最佳实践,因此不推荐(按 Check 样式)。

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

8 回答 8

16

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

但是 Java 7 有一个可以使用的multi-catch语句:

catch(IllegalArgumentException | IllegalAccessException | IOException exception) {
    handleException(e);
}
于 2012-07-16T18:24:52.240 回答
6

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

于 2012-07-16T18:25:17.017 回答
3

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

try{

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

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

在较旧的 Java 版本中,捕获常见的子类(Exception其中一种情况)确实不是一个坏主意。总是不加考虑地这样做是不好的,但是如果您考虑过并选择它作为最佳解决方案,就可以这样做。

于 2012-07-16T18:25:24.063 回答
3

与 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。但是你的代码看起来更好......

于 2012-07-16T18:26:03.223 回答
3

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

try {
  // do stuff
} catch (RuntimeException e) { 
  throw e; 
} catch (Exception e) { 
  throw new RuntimeException(e); 
}
于 2012-07-16T18:29:57.793 回答
1

大家觉得这个解决方案怎么样?

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的任何可能的副作用?
于 2012-07-17T18:42:51.227 回答
0

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

于 2012-07-16T18:27:15.187 回答
0

您的代码看起来像您打算这样做:

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

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

捕获所有异常并让所有错误通过很少是正确的事情,但捕获一长串任意选择的不相关异常则更不可能是正确的事情。

您的例外列表看起来相当可疑。即为什么你会捕捉到 IllegalArgumentException 而不是 NullPointerException 或 ClassCastException ,它们在语义上处于相似的级别。而且你似乎是在结合IO使用Reflection,所以你可能还要处理NoClassDefFoundError、ExceptionInInitializerError等错误。那么 StackOverflowError 甚至 OutOfMemoryError 呢...

于 2012-07-17T03:54:44.347 回答