有一个try-catch块,你应该在其中放置所有语句还是只放置不安全的语句?

Bin*_*Bob 10 java exception-handling

假设save抛出并且i仅用于save.以下代码片段是否相同?请考虑语义,性能和其他方面.

void bob(){
  int i = calculate();
  try {
    save(i);
  } catch(Exception e){
    report(e)
  }
}
Run Code Online (Sandbox Code Playgroud)

void bob(){
  try {
    int i = calculate();
    save(i);
  } catch(Exception e){
    report(e)
  }
}
Run Code Online (Sandbox Code Playgroud)

一般来说,我想知道,如果一个函数的所有语句都放在一个try-catch块中,或者只是一个抛出.

The*_*kis 11

从语义学的角度来说,如果你已经确定了将try-catch构造放入哪种方法(并且你觉得你已经正确地做出了这个决定),那么答案很简单:

  • 您应该在try块中包含一系列语句,如果其中一个语句失败,则应该放弃序列的其余部分.没有更多,也没有更少的陈述.

如果您正确地遵循上述建议,那么很容易且很明显地(在大多数情况下)解决诸如所需程序流和最有效的局部变量范围之类的问题.您会注意到这并不排除嵌套try块的可能性.

性能方面,异常处理的开销在于实际抛出和捕获可抛出对象.换句话说,只有在实际发生异常时才真正有开销.代码中仅存在try-catch构造不会引入任何可测量的开销(可能根本没有).此外,语句的数量(在给定的try-catch构造内)与其性能完全无关.

编辑:我找不到要链接到的JVM规范中的任何细节,但有很多用户检查和解释生成的字节码的帖子,比如这个这个(在许多其他人中 - 谷歌搜索会产生一些有趣的结果).对我来说,看起来Java编译器尝试尽可能少地发出(当然,除了你放入的实际代码trycatch子句和一些不可避免的程序流指令跳转到所述子句或弹出异常对象,如果有的话).它留给VM负责找出异常被捕获的位置.这很可能会将更多的负担转移到实际发生异常的场景中,但是,正如我们所知,异常是针对特殊情况,而不是控制流.

我承认我不知道C++异常通常是如何实现的,但考虑到C++程序通常不在VM的帮助下运行,它们与Java完全不同是非常合理的.


Roh*_*ain 5

他们不一样.不同之处在于变量的范围i.在第二种情况下,你不能itry-catch街区之外使用.

一般来说,我想知道,如果一个函数的所有语句都放在try-catch块中,或者只是抛出一个函数.

更好的方法是将代码容易包装在try-catch块中抛出异常.这样,您就可以处理与特定代码块相关的特定异常.所以,第一种方式是要去的方式.