我应该从方法中抛出的异常数量是否有限制?

时间:2009-10-11 04:42:02

标签: java performance

以这种方式声明功能会对性能产生什么影响?

public init(){
    try{
         initApplication();
     }catch(A1Exception){

     }catch(A2Exception){

     ...
     }catch(A5Exception){

     }
}

private void initApplication() throws A1Exception, A2Exception, A3Exception, A4Exception, A5Exception {
   initApp1(); //throws A1, A2, A3
   initApp2(); //throws A4, A5
}

以这种方式实现initApplication()是否存在任何问题?

9 个答案:

答案 0 :(得分:4)

近年来,人们一直认为检查异常是相当有害的。如果检查了这些异常中的每一个,则强制调用方法必须处理它们或声明它们。这打破了封装,因为现在某些较低级别的实现细节会泄漏到更高级别。

Joshus Bloch在Effective Java中谈到了这一点,我强烈推荐。

答案 1 :(得分:1)

我没有看到抛出代码所需的异常的问题。在查看示例时,我的第一印象是此处可能使用Exceptions来控制应用程序的流程。小心不要这样做。只有在特殊情况下才会触发例外情况。

不应通过Exceptions处理流程流的一个原因是,提高Exceptions是一个昂贵的过程。虽然多个catch块的结构不会导致性能损失,但使用Exceptions控制流的(潜在)底层进程可能效果不佳。

考虑到这一点,是否有“气味”?只有在设计代码时上述问题属实。

答案 2 :(得分:1)

对于方法可以抛出多少异常没有限制。 抛出的异常越多,您对捕获的异常的具体情况就越多。

我想指出一些我遵循的建议。 1)Atleast在最后有一个通用异常,所以如果你的代码中可能出现的任何其他异常被捕获而不是抛出到调用类。 2)您可以拥有类别的异常类,如BusinessLogic异常,InvalidDataException,SystemsException,这样您实际上可以减少从任何方法抛出的异常。 (除非您的业务要求完全例外 3)总是有错误代码而不是抛出实际的文本消息,这将使您的应用程序语言独立。

答案 3 :(得分:0)

<强> Q1 即可。这会对性能产生影响吗?

  • 不,如果它们是“真正的”例外(即用于正常的程序控制流程),则不是。

<强> Q2 即可。你在initApplication()看到了气味吗?

  • 不,如果initApplication()可以提出N个例外,即如果有N个特殊情况可能会阻止initApplication()完成它的工作,那就不行了。

答案 4 :(得分:0)

1:性能影响最小......

2:但这不一定是个好主意,因为过多的锅炉板代码会让人难以阅读。如果要以相同的方式处理每个异常,那么您应该捕获基类Exception。或者你可以让initApplication()抛出一个自定义异常 - 类似于ApplicationInitializationException,它传达了更多关于出错的意义。您可以将异常消息设置为确切的详细信息。

在某些情况下,您可能会获得5种不同的异常,并且可能必须以不同方式处理所有异常。在这种情况下,抓住所有5个将是正确的事情。但在实施之前,有必要考虑一下这是否真的有必要。

答案 5 :(得分:0)

如果没有异常没有性能影响,如果抛出异常,会有一些开销发现匹配的catch会随着你添加更多异常而增长,但它应该没关系,因为异常应该是......例外的。不应该在一般情况下发生。

换句话说,如果你不使用抛出异常来控制你的程序流程,你应该没问题,如果你这样做,无论你有多少catch子句,这肯定是一种气味

答案 6 :(得分:0)

在纯技术说明中,class文件格式引入了65536例外的上限。 u2类型的exceptions_table_length是无符号双字节数量的简写。

The Code attribute has the following format:

Code_attribute {
 u2 attribute_name_index;
 u4 attribute_length;
 u2 max_stack;
 u2 max_locals;
 u4 code_length;
 u1 code[code_length];
 u2 exception_table_length;
 {     u2 start_pc;
        u2 end_pc;
        u2  handler_pc;
        u2  catch_type;
 } exception_table[exception_table_length];
 u2 attributes_count;
 attribute_info attributes[attributes_count];
}

我只会在你生成代码的情况下提出这个问题。 JSP开发人员经常不得不担心生成的方法超过64KB代码大小的问题。 Section 4.10 Limitations of the Java Virtual Machine中列出了此限制和其他限制。

答案 7 :(得分:0)

我想这个答案主要与第二季度有关,但是对它的看法并不是那么技术性但是可能值得考虑的是以下两个问题背后的问题?

  • 用户是否有理由捕获所有这些内容?
  • 你是否想要让用户厌倦了拥有大量的catch块,而只是插入一个“catch(Exception ex){// ex.printStackTrace(); //如果我们看到问题就启用它”}或类似的东西和愚蠢的东西。?

在这种情况下,我想这可能不相关,但我认为在进行一般的API设计时,值得考虑。

答案 8 :(得分:0)

除非您在捕获异常时采取行动,否则不要抛出任何异常。将已检查的异常转换为运行时异常以进行日志记录。

可以找到有关该主题的更多信息here