Java 有一个try-catch块,您应该将所有语句都放在其中还是只放在不安全的语句中?
假设Java 有一个try-catch块,您应该将所有语句都放在其中还是只放在不安全的语句中?,java,exception-handling,Java,Exception Handling,假设save抛出并且i仅用于save。以下代码片段是否相同?请参阅符号学,性能< /强>等方面。 void bob(){ int i = calculate(); try { save(i); } catch(Exception e){ report(e) } } vs 通常我想知道的是,应该将函数的所有语句放在一个try catch块中,还是只放在抛出的语句中。它们是不同的。差异在于变量i的范围。在第二种情况下,不能在try catch块之外使用i 通常我想知
save
抛出并且i
仅用于save
。以下代码片段是否相同?请参阅符号学,<强>性能< /强>等方面。
void bob(){
int i = calculate();
try {
save(i);
} catch(Exception e){
report(e)
}
}
vs
通常我想知道的是,应该将函数的所有语句放在一个
try catch
块中,还是只放在抛出的语句中。它们是不同的。差异在于变量i
的范围。在第二种情况下,不能在try catch
块之外使用i
通常我想知道,应该将函数的所有语句放在try-catch块中,还是只放在抛出的块中
更好的方法是将容易引发异常的代码包装在
try-catch
块中。这样,您可以处理与特定代码块相关的特定异常。因此,第1种方法是应该采用的方法。语义方面,如果您已经决定了要将try-catch构造放在哪个方法中(并且您对正确做出该决定感到满意),那么答案相当简单:
- 您应该在
块中包含一个语句序列,这样,如果其中一个语句失败,则应放弃序列的其余部分。不多也不少try
try
块的可能性
就性能而言,异常处理的开销在于实际抛出和捕获可丢弃对象。换句话说,只有在实际发生异常时才有真正的开销。代码中仅仅存在一个try-catch构造不会引入任何可测量的开销(可能根本没有)。此外,语句的数量(在给定的try-catch构造中)与其性能完全无关
编辑:我在JVM规范中找不到任何可链接的细节,但用户发布了许多帖子,检查和解释生成的字节码(以及其他许多帖子——谷歌搜索将产生一些有趣的结果)。在我看来,Java编译器似乎尽可能少地发出代码(当然,除了放入try
和catch
子句中的实际代码,以及一些不可避免的程序流指令,以跳过上述子句或弹出异常对象(如果有的话)。它让VM负责找出异常可能被捕获的位置。这很可能会将更多的负担转移到实际发生异常的场景中,但正如我们所知,异常是针对异常情况的,而不是控制流
<>我承认我不知道C++异常是如何实现的,但是从Java的角度来看,这是非常合理的,因为C++程序通常不在VM的帮助下运行。 < P> Rohit指出(正确地)变量calculate()
抛出未检查的异常;它将被catch
块捕获。您是否应该在try
块中调用calculate()
,取决于您是要处理catch
块中calculate()
中未检查的异常,还是允许它向外抛出。在我看来,因为它是未选中的,因此完全出乎意料,所以我不会在try
块中调用calculate()
关于性能,我认为不应该有什么区别,因为性能影响是在遇到try
块时发生的,并且在这两种情况下只有一个块。如果您在每一行周围有单独的try catch
块,如下所示,那么性能可能会降低,但可能不会以您从未注意到的任何方式降低:
// degraded performance example
void bob(){
int i;
try {
i = calculate();
} catch(Exception e){
report(e)
}
try {
save(i);
} catch(Exception e){
report(e)
}
}
在这种情况下:
void bob(){
try {
int i = calculate();
save(i);
} catch(Exception e){
report(e)
}
}
将捕获所有异常(错误除外),因为异常是所有类型的异常
(错误除外)的超类。因此,不仅会处理选中的异常,还会处理未选中的异常,如RuntimeException
。如果这是你的目标,那么我建议你这样做。
另一方面,我认为最小化try…catch块的范围是一个好的做法,因为在出现异常的情况下,定位有问题的代码行更容易。性能如何?我知道一个
try-catch
会造成一些延迟,但它是否取决于包装块的大小?在分析代码并发现这是一个问题之前,不要担心这一点。我不会过早优化,我避免过早悲观;>@try-catch构造没有任何显著的开销。实际捕获异常的行为可能会带来您可能担心的开销。可能与您自己尝试查找的内容重复?请参阅我编辑的答案,我已经包含了一段关于性能问题的内容。回答很好,你是否有一些材料证明了try-catch
的存在不会带来任何成本?因为在C++中简单地使用这个结构,改变了编译代码看起来在堆栈和堆上添加多个操作和元素的方式。我相信JLS指定了try
块中,除非有问题的异常是check
void bob(){
try {
int i = calculate();
save(i);
} catch(Exception e){
report(e)
}
}