英文:
Why use 'try' ' catch' 'finally' to handle exception
问题
老师说,使用异常测试可以提高程序的健壮性。显然这是正确的。
但这里存在一个悖论。
如果我没有意识到程序的这部分可能会出现异常,我也不会使用try{}!
如果我意识到这个程序可能会有异常,为什么不修复这个程序,使其更加健壮呢?
例如,简单的函数
function c=div(a,b)
c=a/b;
end
如果b=null或b=0或b是字符,就会发生异常,为什么我要使用
function c=div(a,b)
try{c=a/b;
}
catch (子类){…………
}
catch(父类){…………
}
catch(异常 e){…………
}
end
为什么我不使用switch case + @NotEmpty @NotNull isDigit()来验证输入参数呢?
如果你发现桶漏水了
try catch帮助你把漏出的水倒回桶里
但为什么我不堵住桶的漏洞呢?
如果你没有注意到桶在漏水
try catch也帮不了太多
这就是我的困惑
英文:
The teacher said that using exception testing can improve the robustness of the program. Clearly it is true.
But there is a paradox here.
If I didn't realize that this section of the program may have exception. I wouldn't use try{} either!
If I realize that this program may be has exception, why don't I fix this program to make it more robust?
For example,simple function
function c=div(a,b)
c=a/b;
end
If b=null or b=0 or b is char ,there will be an exception, why do I have to use
function c=div(a,b)
try{c=a/b;
}
catch (children class){…………
}
catch(parent class){…………
}
catch(exception e){…………
}
end
Why do not I use a switch case + @NotEmpty @NotNull isDigit() to verify that the input parameters?
If you find that the bucket is leaking
try catch helps you pour the leaked water back into the bucket
But why don't I plug the bucket hole?
If you don't notice the bucket is leaking
try catch doesn't help much either
this is my confusion
答案1
得分: 0
这不是事先知道或不知道您的程序可能在某些特定的代码块中抛出异常的问题。而是能够在发生“某事”的情况下进行恢复。例如,如果错误导致您的应用程序崩溃,会产生负面后果:
- 一些已打开的资源可能无法正确关闭(取决于操作系统和一堆其他因素)。
- 用户体验很糟糕:人们不喜欢看到他们正在使用的应用程序发生致命崩溃。
然而,如果您将逻辑包装在try-catch
块中,您可以从错误中恢复(当然,并非总是如此,这取决于错误)。
然后您可能会问:“为什么不只是将整个程序包装在超级try-catch
块中呢?”好吧,您可以这样做。但问题是,大多数情况下,“恢复”取决于两件事:
- 到底发生了什么类型的错误?
- 它确切地发生在哪里?
根据这些答案,您将尝试以一种或另一种方式恢复应用程序流程,如果您只是在整个应用程序周围有一个终极的try-catch
,这将是有问题的 - 如果不是不可能的话。
您的后续问题可能是:“那么,我该如何决定我的try-catch
的粒度?”我的代码库中应该有多少个try-catch
?我应该多频繁地插入它们?我应该将每一行都包装在自己的try-catch
中吗?或者每个函数/方法都包含它是否可以?
好吧,这是个好问题,因为这里没有银弹。这实际上取决于您的代码和您使用的具体编程语言。例如,某些编程语言(如Java)有所谓的“受检异常”:如果某个函数定义了一个受检异常,那么当您调用此函数时(或稍后,在调用堆栈的某个地方)必须捕获它。有些语言没有这个概念。此外,要记住不同的编程范式:过程式编程、函数式编程、面向对象编程等等。所有这些都会影响您处理异常的策略。作为一个经验法则,您可以遵循一个建议,每当您打开某个资源(文件、数据库连接等)时,将其包装在try-catch-finally
中,并确保在finally
块中关闭此资源。有些语言(如Java)甚至为此提供了一个特殊的语法,称为try-with-resources。
英文:
It's not about knowing or not knowing in advance that you program may throw an exception in some particular code block. It's about being able to recover if "something" happens. For example, if the error causes your application to crash, it results in negative consequences:
- Some opened resources may not get closed properly (depends on OS and a bunch of other factors).
- User experience is bad: people don't like seing fatal crashes of the apps they are using.
However, if you wrap your logic in a try-catch
block, you are able to recover from getting an error (not always, of course, - depends on the error).
Then you may ask: "Why not just wrap the whole program in an uber-try-catch
block"? Well, you can. But the things is that most of the time "recovery" depends on two things:
- What type of error did happen?
- Where exactly did it happen?
Depending on the answers, you will try to restore the app flow one way or another, which would be problematic - if not impossible - if you just had an ultimate try-catch
wrapping your whole app.
Your follow-up question may be: "But then, how do I decide on the granularity of my try-catch
es"? How many of them should I have across my codebase? How frequently should I insert them? Should I wrap every single line into its own try-catch
? Or it is fine to have it per function/method?
Well, these are good questions, because there's no silver bullet here. It really depends on your code and on the specific programming language you are using. For example, some PLs (like Java) have so-called "checked exceptions": if some function defines a checked exception, then you must catch it when you call this function (or later, at some point, upper in the call stack). Some languages don't have this concept. Also, keep in mind different paradigms: procedural programming, functional programming, OOP, etc. All of this impacts your strategy of handling exceptions. As a rule of thumb, you may follow a recommendation that whenever you open some resource (file, DB connection, etc.) - wrap it in try-catch-finally
and make sure to close this resource in the finally
block. Some languages (like Java) even have a special syntax for this, called try-with-resources.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论