29 defensive-programming exception-handling
我在过去的3年里一直在编程.当我编程时,我用来处理所有已知的异常并优雅地提醒用户.我最近看到了一些代码,几乎所有方法都包含在try/catch块中.作者说它是防御性编程的一部分.我想知道,这真的是防御性编程吗?您是否建议将所有代码放入try块中?
Jam*_*ran 57
我的基本规则是:除非你能解决导致异常的问题,否则不要抓住它,让它冒泡到一个可以处理它的水平.
根据我的经验,所有catch块中有95%要么只是忽略异常(catch {}),要么只记录错误并重新抛出异常.后者可能看起来是正确的做法,但在实践中,当在每个级别完成此操作时,您最终只会将您的日志与同一错误消息的五个副本混杂在一起.通常这些应用程序在最顶层有一个"忽略捕获"(因为"我们已经尝试/捕获所有较低级别"),导致一个非常慢的应用程序,有很多错过的异常,并且错误日志太长了任何人都愿意透过它看.
Roa*_*ior 19
广泛使用Try ... Catch不是防御性编程,它只是将尸体钉在直立的位置.
尝试...最后可以在面对意外异常时广泛用于恢复.只有当你期望一个例外,现在如何处理它时,你应该使用Try..Catch.
有时我会看到Try..Catch System.Exception,其中catch块只记录异常并重新抛出.这种方法至少有3个问题:
Bil*_*win 14
不,这不是"防御性编程".你的同事试图通过使用流行语来养成良好的习惯,从而使他的坏习惯合理化.
他正在做的事情应该被称为"在地毯下扫地".这就像(void)从方法调用中统一处理错误状态返回值一样.
Aar*_*lla 11
术语"防御性编程"代表编写代码,使其能够从错误情况中恢复或完全避免错误情况.例如:
private String name;
public void setName(String name) {
}
Run Code Online (Sandbox Code Playgroud)
你如何处理name == null?你抛出异常还是接受它?如果没有名称的对象没有意义,那么你应该抛出异常.怎么样名字==""?
但是......后来你写了一个编辑器.在设置UI时,您会发现在某些情况下,用户可以决定取消名称,或者在用户编辑名称时该名称可能为空.
另一个例子:
public boolean isXXX (String s) {
}
Run Code Online (Sandbox Code Playgroud)
在这里,防御策略通常在s == null时返回false(当你可以时避免使用NPE).
要么:
public String getName() {
}
Run Code Online (Sandbox Code Playgroud)
如果name == null,防御程序员可能返回""以避免调用代码中的NPE.
如果你要处理随机异常,只在一个地方处理它们 - 应用程序的最顶层,用于:
对于其他一切,您希望最直接的,特定于位置的崩溃成为可能,以便您尽早捕获这些内容 - 否则异常处理将成为隐藏草率设计和代码的一种方式.
在异常可预测的大多数情况下,可以提前测试异常处理程序将捕获的条件.
一般来说,如果......其他比Try ... Catch要好得多.
捕获随机异常很糟糕.然后怎样呢?
捕获实际上可以做一些有意义的事情的例外是好的.这些案例易于识别和维护.
我可以在这里说一下,每当我的一个同事用"抛出异常"写一个方法签名而不是列出方法真正抛出的异常类型时,我想过去拍脑袋吗?问题是,经过一段时间你有14个级别的调用,所有这些都说"抛出异常",所以重构让他们宣布他们真正抛出的东西是一个重要的练习.
有一个"太多"处理的事情,捕捉所有异常有点失败的意义.特别是对于C++,catch(...)语句会捕获所有异常,但是您无法处理该异常的内容,因为您不知道异常的类型(并且它可以是任何异常).
您应该捕获可以完全或部分处理的异常,重新抛出部分异常.你不应该捕获任何你无法处理的异常,因为这只会混淆可能(或者更确切地说)稍后会咬你的错误.
| 归档时间: |
|
| 查看次数: |
9616 次 |
| 最近记录: |