有人告诉我,使用 Java 的 try-catch 机制会产生一些开销。因此,虽然有必要将抛出已检查异常的方法放在 try block 中以处理可能的异常,但从性能角度来看,最好将 try block 的大小限制为仅包含可能抛出异常的那些操作。
我不太确定这是一个合理的结论。
考虑以下两个处理指定文本文件的函数的实现。
即使第一个确实会产生一些不必要的开销,我发现它更容易理解。仅通过查看语句就不太清楚异常究竟来自何处,但评论清楚地表明了哪些语句是负责任的。
第二个比第一个更长更复杂。特别是,第一个很好的读行习惯必须被破坏以使 readLine
调用适合 try block 。
在定义中可能引发多个异常的函数中处理异常的最佳做法是什么?
这个包含try block 内的所有处理代码:
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 block 中抛出异常的方法:
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);
}
}
最佳答案
这里的基本前提是false: try
block 的大小对性能没有影响。性能会受到运行时实际引发异常的影响,这与 try
block 的大小无关。
但是,保持较小的 try block 可以产生更好的程序。
您可能会捕获异常以恢复和继续,或者您可能会捕获它们只是为了将它们报告给调用者(或通过某些 UI 向人类报告)。
在第一种情况下,您可以从中恢复的故障通常非常具体,这会导致较小的 try
block 。
在第二种情况下,一个异常被捕获,以便它可以被另一个异常包装并重新抛出,或显示给用户,小的 try
block 意味着您可以更准确地知道哪个操作失败,以及进行该调用的更高级别的上下文。这允许您创建更具体的错误报告。
当然,这些指南有……异常(exception)(抱歉!)。例如,在某些情况下,非常具体的错误报告可能是一个安全问题。
了解 try
block 对编译代码的影响可能很有用。它根本不会改变编译的指令! (当然,相应的 catch
block 可以,因为它与任何其他代码一样。)
try
block 在与方法关联的异常表中创建一个条目。该表具有一系列源指令计数器、异常类型和目标指令。当引发异常时,将检查此表以查看是否存在具有匹配类型的条目,以及包含引发异常的指令的范围。如果是,则执行分支到相应的目标编号。
要意识到的重要一点是,除非需要,否则不会查询此表(并且对运行性能没有影响)。 (忽略加载类的一点开销。)
关于java - java try block 的范围是否应该尽可能紧密?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2633834/