2013-05-06 67 views
2

我正在为一个框架的Java插件工作。Java异常处理 - 这是一个好的做法吗?

我写我的代码以这样一种方式,入口函数看起来像下面(认为这是出发点,主要功能)

function entryPoint() 
{ 
    try{ 
     //some code block 
     subFunction1(); 
     subFunction2(); 
    } 
    catch(Exception e) {} 
    catch(IOException ioe) {} 
    catch(NullPointerException npe){} 
} 

function subFunction1() throws IOException 
{ 
    //some code 
} 

function subFunction2() throws NullPointerException 
{ 
    //some code 
} 

这样的想法是,所有的子功能将引发特定的例外主要功能和 我们捕捉这些例外的主要功能,并做处理。

这是正确的吗?如果不是,请提出更好的方法。

+1

首先捕捉'Exception'至少不会做任何事情。但无论如何,这是太多的宗教/意见与异常处理... – NilsH 2013-05-06 08:08:24

+3

你永远不应该赶上你自己的NPE。它们表示一个*编码*错误,应该是固定的,而不是被捕获。 – dlev 2013-05-06 08:10:09

+0

@NilsH:是的。我发现多个堆栈溢出的答案,这表明多种方法。但是这种方法不是一个好的设计? – balanv 2013-05-06 08:10:40

回答

10
  • 应该更改catch声明的顺序。由于第一个catch将匹配所有Exceptions,因此以下两个决不会被触发。

  • 在大多数情况下,NPE是意想不到且无法恢复的。捕捉它意味着应用程序能够从中恢复并运行。这是真的吗?

  • 即使NPE是可恢复的,最好检查!= null而不是依赖命令流的异常。这是出于概念上的原因(基于异常的命令流需要更多的代码,可读性较差,意图通常不清楚)以及性能方面的原因。

  • 所有Exceptions都被吞下 - 没有记录或重新发生。这样,没有人会知道是否以及何时出现问题,因为没有例外记录。在大多数情况下,用户,其他开发人员和维护人员都期望几乎所有的异常都是非常特殊的,因此被记录。

0

我认为这种方法是完美的。人们应该尝试处理特定的异常,而不是一个个处理。把一个try-catch块放在这里就不是它的用处,而是滥用try-catch的东西。

是的异常应该是最后一个要处理的。被误解了。

总之,你的意图是好的,在语法上你可以依赖编译器。

1

不要捕捉或抛出NullPointerException和异常的catch块应该是最后一个

0

你应该做你会做,如果是没有插件的异常处理方式相同。这取决于你的应用程序,如果你可以在一个主要方法中处理所有异常。如果存在可以继续工作的情况,那么这可能很困难。

我会做的关于插件的唯一事情是所有周围的“全部”,也许还有一些特殊的情况下做一些更详细的日志记录。如果框架本身没有这样做,这也只是要做。

0

我认为最好是在第一个可能的位置捕捉​​异常,以便实际解决所产生的问题。

一个例子:

function int divide(int a, int b) throws DivisionByZeroException { 
    if(b == 0){ 
     throw new DivisionByZeroException(); 
    } 
    return a/b; 
} 

function int doCalculationsAndStuff(int a, int b) throws DivisionByZeroException { 
    int result = divide(a, b); 
    ... 
    return result; 
} 

function void main() { 
    try { 
     int a = userInput(); 
     int b = userInput(); 
     int result = doCalculationsAndStuff(a, b); 
     print("result: " + result); 
    } catch(DivisionByZeroException e) { 
     print("Division by zero happened. But i catched it for you =)."); 
    } 
} 

这将没有意义的处理异常divide()doCalculationsAndStuff()。因为在除零的情况下你会返回什么价值?什么都没有,这就是为什么我们抛出异常,并在main函数中处理它,我们给我们的计算器应用程序的用户一些反馈。

现在回到你的问题。如果entryPoint函数是第一个可以解决子函数中出现的问题的地方,那么这是一个处理它们的好地方。