try / catch / throw和try / catch(e)/ throw e的区别

有什么区别

try { } catch { throw; } 

 try { } catch(Exception e) { throw e;} 

而我应该什么时候使用一个或另一个?

build设

 try { ... } catch () { ... } /* You can even omit the () here */ try { ... } catch (Exception e) { ... } 

是类似的,都将捕获在try块内引发的每个exception(除非你只是用这个来loggingexception,应该避免 )。 现在看看这些:

 try { ... } catch () { /* ... */ throw; } try { ... } catch (Exception e) { /* ... */ throw; } try { ... } catch (Exception e) { /* ... */ throw e; } 

第一个和第二个try-catch块是完全一样的东西,他们只是重新抛出当前的exception,而这个exception将保持其“源”和堆栈跟踪。

第三个try-catch块是不同的。 当它抛出exception时,它会改变源和堆栈的跟踪,这样看起来这个exception是从这个方法抛出的,就是从包含该try-catch块的方法中throw e

你应该使用哪一个? 这真的取决于每个案例。

假设你有一个带有.Save()方法的Person类,它将它保存到数据库中。 假设您的应用程序在某处执行了Person.Save()方法。 如果你的DB拒绝保存Person,那么.Save()会抛出exception。 在这种情况下,你应该使用throw还是throw e ? 那么,这取决于。

我更喜欢做的是:

 try { /* ... */ person.Save(); } catch(DBException e) { throw new InvalidPersonException( "The person has an invalid state and could not be saved!", e); } 

这应该把DBException作为抛出新的exception的“内部exception”。 所以,当你检查这个InvalidPersonException时,堆栈跟踪将包含信息回到Save方法(这可能足以解决问题),但是如果你需要的话,你仍然可以访问原始exception。

最后一句话,当你期待一个exception时,你应该真的捕获到一个特定的exception,而不是一个普通的Exception ,也就是说,如果你期待InvalidPersonException,你应该更喜欢:

 try { ... } catch (InvalidPersonException e) { ... } 

 try { ... } catch (Exception e) { ... } 

祝你好运!

首先保留堆栈跟踪,而第二个重置它。 这意味着如果使用第二种方法,则exception的堆栈跟踪将始终从此方法开始,并且您将失去原始exception跟踪,这对于读取exception日志的人来说可能是灾难性的,因为他将永远不会找出exception的原因。

第二种方法可能是有用的,当你想添加额外的信息到堆栈跟踪,但它是这样使用:

 try { // do something } catch (Exception ex) { throw new Exception("Additional information...", ex); } 

有一个博客文章讨论了差异。

你应该使用

 try { } catch(Exception e) { throw } 

如果你想在抛出exception之前做一些事情(例如logging日志)。 孤独的投掷保存堆栈跟踪。

无参数catch和catch(Exception e)之间的区别是你得到一个exception的引用。 从框架版本2中,非托pipe的exception被包装在一个托pipe的exception中,所以无参数的exception对任何东西都不再有用。

throw;之间的区别throw; throw e; 第一个用于重新抛出exception,第二个用于抛出新创build的exception。 如果您使用第二个重新抛出exception,它会将它视为一个新的exception,并将其最初抛出的所有堆栈信息replace掉。

所以,你不应该使用问题中的任何一种select。 你不应该使用无参数的catch,而应该使用throw; 重新抛出exception。

而且,在大多数情况下,对于所有exception,您应该使用比基类更具体的exception类。 你应该只捕捉你预期的例外。

 try { ... } catch (IOException e) { ... throw; } 

如果要在重新抛出exception时添加任何信息,则会创build一个具有原始exception的新exception作为内部exception来保留所有信息:

 try { ... } catch (IOException e) { ... throw new ApplicationException("Some informative error message", e); }