Why can't I write just a try with no catch or finally?
有时我这样做,我也看到其他人这样做:
VB:1 2 3 4 | Try DontWannaCatchIt() Catch End Try |
C:
1 2 3 4 5 | try { DontWannaCatchIt(); } catch {} |
我知道我应该抓住我期待的每一个重要的例外,并为此做些什么,但有时这并不重要——或者我做了什么错事?
现在我明白了原因,至少我应该对空catch块进行注释,这样其他人就可以理解为什么它是空的了。我也应该只抓住我期待的例外。
幸运的是,我正在用vb编码,这样我就可以用一个catch编写它:
1 2 3 4 5 6 7 |
如果你不想抓住它,为什么一开始就使用
一个
所以你估计:
1 2 3 4 5 6 7 8 9 | try { //Something that can go wrong } catch { //An empty catch means I can handle whatever goes wrong. If a meteorite hits the //datacenter, I can handle it. } |
接住会吞下任何发生的例外。你对你的代码有信心,你能优雅地处理任何出错的事情吗?
要做的最好的事情(为了您和您的维护程序员的理智)是明确地声明您可以优雅地处理:
1 2 3 4 5 6 7 8 9 10 | try { //Something that could throw MeteoriteHitDatacenterException } catch (MeteoriteHitDatacenterException ex) { //Please log when you're just catching something. Especially if the catch statement has side effects. Trust me. ErrorLog.Log(ex,"Just logging so that I have something to check later on if this happens.") } |
不,你不应该抓住每一个重要的例外。捕获和忽略您不关心的异常是可以的,比如I/O错误,如果您无法对其进行纠正,并且您不想麻烦向用户报告它。
但是您需要让像
如果您想忽略一个异常,那么最好在代码中为该异常显式地编写一个空的catch块。这就清楚了你忽略了哪些例外。非常正确地忽略异常是一个选择加入过程,而不是选择退出过程。拥有一个"忽略所有异常"特性,然后可以被重写为不忽略特定类型,这将是一个非常糟糕的语言特性。
您如何知道哪些类型的异常是重要的,不应该被捕获?如果有你不知道的例外呢?你怎么知道你不会最终压制你不熟悉的重要错误?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | try { } // I don't care about exceptions. catch { } // Okay, well, except for system errors like out of memory or stack overflow. // I need to let those propagate. catch (SystemException exception) { // Unless this is an I/O exception, which I don't care about. if (exception is IOException) { // Ignore. } else { throw; } } // Or lock recursion exceptions, whatever those are... Probably shouldn't hide those. catch (LockRecursionException exception) { throw; } // Or, uh, what else? What am I missing? catch (???) { } |
这通常是个错误。异常是异常行为的信号;当抛出异常时,它应该意味着出了问题。因此,继续正常的程序流,就好像什么都没有出错一样,这是一种隐藏错误的方法,一种拒绝的形式。相反,考虑一下代码应该如何处理异常情况,并编写代码来实现这一点。由于已将错误覆盖而传播的错误比立即出现的错误更难调试。
另外,如果您没有对一个错误做些什么,也许您应该指定程序必须忽略的异常类型。
如果您必须忽略每个异常,我不明白为什么您不能用这种方式使用try/catch。
存在错误,已引发,需要转到某个位置。正常代码流已中止,需要清洁风扇。
无catch块=不确定状态。代码应该放在哪里?它应该做什么?
空catch块=忽略该块处理的错误。
注意:VBA有一个恶意的"出错时继续"…
这对您来说并不容易,因为大多数开发人员都认为这是不好的做法。
如果后来有人向
如果您必须这样做,请尽可能具体地描述您要捕获的异常类型。如果不是,也许记录异常是一个选项。
没有catch或finally无效。空catch或finally有效。空捕获意味着你不关心异常,你只是尝试做一些事情,如果它不起作用,你就不重要了,你只是想继续下去。例如,在清理函数中很有用。
是的,不正确。就像
吞咽没有任何反应的异常是错误处理中最糟糕的事情之一,它至少应该是明确的:
1 2 3 4 5 6 7 8 9 10 | try { DontWannaCatchIt(); } catch { // This exception is ignored based on Spec Ref. 7.2.a, // the user gets a failure report from the actual results, // and diagnostic details are available in the event log (as for every exception) } |
远处看:
错误处理是一个方面:在某些情况下,需要抛出错误并向上传播调用堆栈(例如,复制文件,复制失败)。
在不同的上下文中调用相同的代码可能需要跟踪错误,但操作要继续(例如,复制100个文件,日志指示哪些文件失败)。
即使在这种情况下,空的catch处理程序也是错误的。
对于大多数语言,除了在循环中尝试+catch并在catch处理程序中构建日志之外,没有其他直接实现。(不过,您可以构建一个灵活的MROE机制:拥有一个每个调用线程的处理程序,该处理程序可以抛出或收起消息。但是,在没有直接语言支持的情况下,与调试工具的交互会受到影响。)
一个合理的用例是从一个
如果你只用try只写代码怎么办?
1 2 3 4 5 | try { int j =0; 5/j; } |
这相当于写
1 2 | int j =0; 5/j; |
所以写尝试没有任何意义,它只会增加你的行数。
现在,如果您使用空catch或finally编写try,您将明确地指示运行时采取不同的行为。
所以这就是为什么我认为空的try块是不可能的。
我听说的原因是,如果您的尝试因任何原因失败,那么让您控制错误响应比让框架控制它(即黄屏或错误500)要好得多。