try/catch/throw和try/catch(e)/throw e之间的区别是什么?

13 浏览
0 Comments

try/catch/throw和try/catch(e)/throw e之间的区别是什么?

try { }
catch
{ throw; }

\n与\n

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

\n之间有什么区别?\n在什么情况下我应该使用其中之一?

0
0 Comments

try/catch/throw和try/catch(e)/throw e之间的区别是,前者保留了堆栈跟踪,而后者重置了堆栈跟踪。这意味着如果使用后一种方法,异常的堆栈跟踪始终将从该方法开始,并且将丢失原始异常跟踪,这对于阅读异常日志的人来说可能是灾难性的,因为他将永远无法找到异常的原始原因。

第二种方法在您想要向堆栈跟踪添加其他信息时可能很有用,但是它的使用方式如下:

try
{
    // 进行一些操作
}
catch (Exception ex)
{
    throw new Exception("Additional information...", ex);
}

当需要检查特定异常(如OutOfRangeException)或需要记录消息时,第二种方法非常方便。第一种方法似乎是类似于C++中的try{}catch(...){}的通配符异常处理程序。

关于这些区别有一个博客文章进行了讨论。

那么为什么要使用第二种方法呢?是否只使用第一种方法更好?

第二种方法在需要检查特定异常时很有用,例如OutOfRangeExcpetion,或者在需要记录消息时。第一种方法似乎是类似于C++中的try{}catch(...){}的通配符异常处理程序。

David,这仅适用于catch (Exception e)部分。这与throw和throw e是分开的。

0
0 Comments

如果将此处的"throw"替换为"throw e",将会导致异常的堆栈跟踪信息丢失。在"throw e"的情况下,新的异常将被创建并抛出,代替原始的异常对象。这样一来,异常的堆栈跟踪信息将从"throw e"的位置开始,而不是从原始异常抛出的位置开始。

为了解决这个问题,可以使用try/catch/throw语句块来捕获异常并重新抛出它,而不是使用try/catch(e)/throw e语句块。这样做可以保留原始异常的堆栈跟踪信息,同时允许在重新抛出异常之前对异常进行处理(比如记录日志)。这种方式可以确保异常的完整堆栈跟踪信息被保留下来,方便定位和调试问题。

因此,正确的做法是使用try/catch/throw语句块来捕获和重新抛出异常,以保留异常的堆栈跟踪信息。使用try/catch(e)/throw e语句块可能会导致堆栈跟踪信息的丢失。

0
0 Comments

try/catch/throw和try/catch(e)/throw e之间的区别是什么?这个问题的出现原因是什么?应该如何解决?这两种结构在捕获try块内抛出的每个异常时是相似的(除非你只是用它来记录异常,应该避免使用)。现在看看下面的代码:

try { ... }

catch ()

{

/* ... */

throw;

}

try { ... }

catch (Exception e)

{

/* ... */

throw;

}

try { ... }

catch (Exception e)

{

/* ... */

throw e;

}

第一个和第二个try-catch块完全相同,它们只是重新抛出当前异常,该异常将保留其“源”和堆栈跟踪。

第三个try-catch块不同。当它抛出异常时,它会更改源和堆栈跟踪,以便似乎异常是从包含该try-catch块的方法中抛出的,从那一行throw e开始抛出。

应该使用哪种方式?这真的取决于每个具体情况。

假设你有一个Person类,其中包含一个将其保存到数据库中的.Save()方法。假设你的应用程序在某个地方执行了Person.Save()方法。如果你的数据库拒绝保存Person对象,那么.Save()将抛出一个异常。在这种情况下,你应该使用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作为新异常的"内部异常"。因此,当你检查这个InvalidPersonException时,堆栈跟踪将包含返回到Save方法的信息(这可能足以解决问题),但如果需要,你仍然可以访问原始异常。

最后一点,当你“期望”一个异常时,你应该真正捕获那个特定的异常,而不是一个通用的Exception,即,如果你期望一个InvalidPersonException,你应该优先使用:

try { ... }

catch (InvalidPersonException e) { ... }

而不是

try { ... }

catch (Exception e) { ... }

0