我刚刚看到一个try-catch问题,人们(包括Jon Skeet)说空的catch块是一个非常糟糕的想法?为什么会这样?难道没有任何情况下空的catch不是错误的设计决策吗?
我的意思是,例如,有时您想要从某个地方(webservice、数据库)获取一些附加信息,您真的不在乎是否能够获取到这些信息。所以您尝试去获取它,如果发生了任何事情,没关系,我只需添加一个“catch(Exception ignored){}”,就可以了。
我刚刚看到一个try-catch问题,人们(包括Jon Skeet)说空的catch块是一个非常糟糕的想法?为什么会这样?难道没有任何情况下空的catch不是错误的设计决策吗?
我的意思是,例如,有时您想要从某个地方(webservice、数据库)获取一些附加信息,您真的不在乎是否能够获取到这些信息。所以您尝试去获取它,如果发生了任何事情,没关系,我只需添加一个“catch(Exception ignored){}”,就可以了。
它们一般来说是个糟糕的想法,因为很少有情况下一个故障(更普遍的是异常条件)不需要任何响应来妥善处理。此外,空的catch
块是使用异常引擎进行错误检查的人常用的工具,而他们本应该采取预防措施。
说它总是不好是不正确的...很少有事情是总是如此。可能有某些情况下你并不关心是否发生了错误,或者错误的存在表示你根本无法采取任何措施(例如,在将先前的错误写入文本日志文件时,如果出现IOException
, 表示您无论如何都无法写出新错误)。
我不会夸大地说那些使用空catch块的人是糟糕的程序员并且不知道自己在做什么...
如果需要,我会使用空catch块。有时候我正在使用的库的程序员并不知道自己在做什么,并在没有必要的情况下抛出异常。
例如,考虑一些http服务器库,如果客户端断开连接并且无法发送index.html
,那么服务器抛出异常对我来说并不重要。
只有在真的发生异常或者出现超出正常情况的情况下,才应该抛出异常。一个空的catch块基本上是在说“出现了糟糕的情况,但我并不关心。” 这是一个不好的想法。
如果你不想处理异常,请让它向上传递,直到达到某个可以处理它的代码。如果没有任何代码可以处理异常,那么它应该导致应用程序崩溃。
catch (Exception) {}
是个不好的想法,但是 catch (SpecificExceptionType) {}
可能完全没问题。程序员使用 catch 子句中的类型信息检查了异常。 - Ben Voigt我认为如果你捕获了一个你知道只针对特定原因而引发的特定异常类型,并且你期望那个异常,而且确实不需要对它做任何处理,那么这是可以的。
但即使是在这种情况下,也可能需要一个调试信息。
有些情况下这样做是可以被证明是合理的。在Python中,您经常看到这种构造:
try:
result = foo()
except ValueError:
result = None
因此,根据您的应用程序,这样做可能是可以接受的:
result = bar()
if result == None:
try:
result = foo()
except ValueError:
pass # Python pass is equivalent to { } in curly-brace languages
# Now result == None if bar() returned None *and* foo() failed
For Each dllFile As String In dllFiles
Try
' Try to load the DLL as a .NET Assembly
Dim dll As Assembly = Assembly.LoadFile(dllFile)
' Loop through the classes in the DLL
For Each cls As Type In dll.GetExportedTypes()
' Does this class implement the interface?
If interfaceType.IsAssignableFrom(cls) Then
' ... more code here ...
End If
Next
Catch ex As Exception
' Unable to load the Assembly or enumerate types -- just ignore
End Try
Next
根据Josh Bloch在Effective Java的第65条建议: 不要忽略异常:
空的catch块通常是由于编码人员不知道自己在做什么。在我们的组织中,空的catch块必须包含一条注释,说明为什么对异常不做任何处理是一个好主意。
另外,大多数人不知道try{}块可以跟随catch{}或finally{},只需要一个。
如果您不知道在catch块中该怎么做,您可以将此异常记录下来,但不要让它保持空白。
try
{
string a = "125";
int b = int.Parse(a);
}
catch (Exception ex)
{
Log.LogError(ex);
}
On Error Resume Next
类似,但是在异常抛出后try块中的任何内容都将被跳过。这并不能帮助解决任何问题。