应该尝试尽可能严格的java范围块?

我被告知使用Java try-catch机制会有一些开销。 因此,虽然有必要将在try块中引发checked checked的方法放在可能的exception处理中,但在性能方面,限制try块的大小只包含那些可能会引发exception的操作是一个很好的做法。

我不太确定这是一个明智的结论。

考虑处理指定文本文件的函数的两个实现。

即使第一个是不必要的开销,我也觉得要容易得多。 目前还不清楚哪些例外情况只是从查看报表而来,但评论清楚地表明了哪些报表是有责任的。

第二个比第一个更长更复杂。 特别的,第一个好的阅读习语必须被修改,以适应readLine调用。

在一个函数中处理exception的最佳实践是什么?

这个包含try块中的所有处理代码:

 void processFile(File f) { try { // construction of FileReader can throw FileNotFoundException BufferedReader in = new BufferedReader(new FileReader(f)); // call of readLine can throw IOException String line; while ((line = in.readLine()) != null) { process(line); } } catch (FileNotFoundException ex) { handle(ex); } catch (IOException ex) { handle(ex); } } 

这个只包含在try块内抛出exception的方法:

 void processFile(File f) { FileReader reader; try { reader = new FileReader(f); } catch (FileNotFoundException ex) { handle(ex); return; } BufferedReader in = new BufferedReader(reader); String line; while (true) { try { line = in.readLine(); } catch (IOException ex) { handle(ex); break; } if (line == null) { break; } process(line); } } 

这里的基本前提是错误的: try块的大小在性能上没有差别。 性能受运行时实际引发exception的影响,这与try块的大小无关。

但是,保持较小的块可以导致更好的程序。

你可能会捕捉exception来恢复和继续,或者你可能只是想把它们报告给调用者(或者通过一些用户界面向人类报告)。

在第一种情况下,可以从中恢复的故障通常是非常具体的,这导致更小的try块。

在第二种情况下,在发生exception的情况下,可以通过另一个exception来包装exception并重新抛出或向用户显示exception,这意味着您可以更精确地知道哪个操作失败,而更高级的上下文这个电话是做的。 这使您可以创build更具体的错误报告。

当然,这些准则有例外(对不起!)。 例如,在某些情况下,非常特定的错误报告可能是一个安全问题。


了解try块对编译后的代码有什么影响可能是有用的。 它根本不会改变编译的指令! (当然,相应的catch块也是这样,因为它和其他代码一样。)

try块在与方法关联的exception表中创build一个条目。 该表具有一系列源指令计数器,一个exceptiontypes和一个目标指令。 当引发exception时,将检查此表以检查是否存在具有匹配types的条目以及包含引发exception的指令的范围。 如果是,则执行分支到相应的目标号码。

要了解的重要一点是,除非需要,否则不会查询此表(并且不会影响运行性能)。 (在加载类中忽略了一点点开销。)

我被告知使用Java try-catch机制会有一些开销。

绝对。 还有方法调用的开销。 但是你不应该把所有的代码放在一个方法中。

不要唠叨过早的优化号angular,但重点应放在阅读,组织等方面。语言构造对系统组织和algorithmselect的影响很less。

对我来说,第一个是最简单的阅读。

不可以。您应该考虑的唯一事情就是您可以合理处理exception情况,以及您需要回收的资源(最终)。

这是最糟糕的过早优化。 不要这样做。

Knuth说:“我们应该忘记效率很低,大约97%的时间:不成熟的优化是所有邪恶的根源。

第二种方法的好处很小。 毕竟,如果你可以成功地打开一个文件,但没有从中读取,那么你的电脑有一些问题。 从而知道ioexception来自readLine()方法是非常有用的。 也正如你所知,无论如何,不​​同的问题抛出不同的问题(FileNotFoundException,等)

只要你用一个“逻辑”块来定义范围,即打开,阅读和closures一个文件,我会用第一种方法去。 读取起来要简单得多,特别是在处理IO时,try-catch开销所使用的处理器周期将是最小的(如果有的话)。

把try块放在可能抛出exception的特定代码周围,使得它在我看来更容易阅读。 您可能希望为每个错误显示不同的消息,并向用户提供说明,根据发生错误的位置,这些说明会有所不同。

然而,大多数人提到的性能问题与提升exception有关,而不是try块本身。

换句话说,只要你没有提出错误,try块就不会明显地影响性能。 你不应该考虑尝试阻止另一个stream控制结构,并提出一个错误来分支你的代码。 这就是你想要避免的。

第二种方法会产生一个编译器错误, reader可能没有被初始化。 你可以通过将它初始化为null来解决这个问题,但这意味着你可以得到一个NPE,这样做没有任何好处。