1什么是稳健性和正确性/h2>
1.健壮性
系统在不正常输入或不正常外部环境下仍能够表现正常的程度
2.面向健壮性的编程
即使终止执行,也要准确/无歧义的向用户展示全面的错误信息
错误信息有助于进行debug
3.稳健性原则(Postel定律)
1.总是假定用户恶意、假定自己的代码可能失败
2.把用户想象成白痴,可能输入任何东西,返回给用户的错误提示信息要详细、准确、无歧义
3.(Postel’s Law):对别人宽容点,对自己狠一点
4.封闭实现细节,限定用户的恶意行为
5.考虑极端情况,没有“不可能”
4.正确性
程序按照spec加以执行的能力,是最重要的质量指标。
正确性与健壮性比较:
正确性:永不给用户错误的结果
健壮性:尽可能保持软件运行而不是总是退出
正确性倾向于直接 错(error),健壮性则倾向于容错(fault-tolerance)
运行时异常:由程序员在代码里处理不当造成,,是程序源代码中引入的故障所造成的
如果在代码中提前进行验证,这些故障就可以避免
其他异常:由外部原因造成,是程序员无法完全控制的外在问题所导致的
– 即使在代码中提前加以验证(文件是否存在),也无法完全避免失效发生。
3 checked和unchecked exception
1.checked exception
必须捕获并指定错误处理器handler,否则编译无法通过,类似于编程语言中的static type checking
发生异常时
–您必须捕获并处理该异常,或者通过声明您的方法引发该异常来告诉编译器您无法处理它,
–然后,使用您的方法的代码将必须处理该异常(如果无法处理该异常,可以选择声明它抛出该异常)。
–编译器将检查我们是否完成了两件事之一(catch或declare)。
2.unchecked exception
可以不处理,编译没问题,但执行时出现就导致程序失败,代表程序中的潜在bug类似于编程语言中的dynamic type checking
编译器不会检查错误error和运行时异常runtime exception
–在这些情况下,您不能做任何事情,但必须重新编写程序代码。所以编译器不会检查这些。
–这些运行时异常将在开发和测试期间发现。然后,我们必须重构代码以删除这些错误。
Java checked exception处理 throws/try catch二选一
(throws) 声明“本方法可能会发生XX异常”
(throw) 抛出XX异常
(try, catch, finally) 捕获并处理XX异常
Unchecked异常也可以使用throws声明或try/catch进行捕获,但大多数时候是不需要的,也不应该这么做——掩耳盗铃,对发现的编程错误充耳不闻
如何选择exception
– 如果客户端可以通过其他的方法恢复异常,那么采用checked exception;
– 如果客户端对出现的这种异常无能为力,那么采用unchecked exception;
– 异常出现的时候,要做一些试图恢复它的动作而不要仅仅的打印它的信息
尽量使用unchecked exception来处理编程错误:因为unchecked exception不用使客户端代码显式的处理它们,它们自己会在出现的地方挂起程序并打印出异常信息。
充分利用Java API中提供的丰富unchecked exception,如NullPointerException , IllegalArgumentException和IllegalStateException等,使用这些标准的异常类而不需亲自创建新的
异常类,使代码易于理解并避免过多消耗内存。
如果client端对某种异常无能为力,可以把它转变为一个unchecked exception,程序被挂起并返回
客户端异常信息
不要创建没有意义的异常,client应该从checked exception中获取更有价值的信息(案发现场具体是什么样子),利用异常返回的信息来明确操作失败的原因。
如果client仅仅想看到异常信息,可以简单抛出一个unchecked exception:
总结:
– Checked exception应该让客户端从中得到丰富的信息。
– 要想让代码更加易读,倾向于用unchecked exception来处理程序中的错误
错误可预料,但无法预防,但可以有手段从中恢复,此时使用checked exception。如果做
不到这一点,则使用unchecked exception
合理的恢复
–告诉调用者预测他们无法恢复的异常是没有意义的。
–如果用户试图读取不存在的文件,调用者可以提示他们输入新文件名。
–另一方面,如果该方法由于编程错误(无效的方法参数或错误的方法实现)而失败,则应用程序无法在执行过程中修复该问题。它所能做的最好的事情就是记录问题,并等待开发人员稍后修复。
除非抛出的异常满足上述所有条件,否则它应该使用Unchecked Exception.
对特殊结果(即预期情况)使用checked exception
使用unchecked exception发出错误信 (意外故障)
5 如何throw exception
在可能出问题处throw exception,并给出提示信息
找到一个能表达错误的Exception类/或者构造一个新的Exception类
构造Exception类的实例,将错误信息写入 ,并抛出它
一旦抛出异常,方法不会再将控制权返回给调用它的client,因此也无需考虑返回错误代码
(不想每个方法都throws声明新定义的异常时)您可能不想强制每个方法在其throws子句中声明您的异常实现。这时可以让新异常类继承runtimeexception
方法可以throw或传播FooRuntimeException异常,而无需声明它。
7 捕捉异常 try catch
A.如果try块中的任何代码引发catch子句中指定的类的异常,则程序跳过try块中的其余代码。执行catch子句中的处理程序代码。
B.如果try块中没有任何代码引发异常,则程序跳过catch子句。
C.如果方法中的任何代码引发catch子句中指定类型以外的异常,则此方法将立即退出。
也可以不在本方法内处理,而是传递给调用方,由client处理(“推卸责任”)(即throws)
尽量在自己这里处理,实在不行就往上传——要承担责任!
但有些时候自己不知道如何处理,那么提醒上家,由client自己处理
如果父类型中的方法没有抛出异常,那么子类型中的方法必须捕获所有的checked exception
子类型方法中不能抛出比父类型方法更多的异常,必须更加具体化或不变
利用 e.getMessage() 获得详细异常信息,利用e.getClass().getName() 获得异常种类
8 re-throw和链接异常
本来catch语句里面是用来做异常处理的,但也可以在catch里抛出异常。
这么做的目的是:更改exception的类型,更方便client端获取错误信息并处理
但这么做的时候最好保留“根原因”
捕获异常时,可以检索原始异常
强烈建议使用这种包装技术。它允许您在子系统中抛出高级异常(se),而不会丢失原始故障的详细信息。
(根据栈中的顺序,逐级弹出,所以最上行是C)
假设methodD()遇到异常情况,并向JVM抛出XxxException。
JVM在调用堆栈中向后搜索匹配的异常处理程序。
它发现methodA()具有XxxException处理程序并将异常对象传递给处理程序
请注意,methodC()和methodB()需要在其方法签名中按顺序声明“throws XxxException”
来编译程序。
5.不要assert外部情况
断言只是检查程序的内部状态是否符合规约
你的代码无法保证不出现此类外部错误
外部错误要使用Exception机制去处理
断言非常影响运行时的性能
3 如何使用assertion
断言->正确性,异常处理->健壮性
使用异常来处理你“预料到可以发生”的不正常情况
使用断言处理“绝不应该发生”的情况
如果参数来自于外部(不受自己控制),使用异常处理
您可以使用断言来测试非public方法的前提条件,如果您认为无论客户机如何处理该类,该前提条件都是真的。
您可以使用public和nonpublic方法中的断言来测postcondition。
开发阶段用断言尽可能消除bugs,在发行版本里用异常处理机制处理漏掉的错误
5 防御式编程
1.防御式编程技术
保护程序免受无效输入的影响:对每个函数的输入
参数合法性要做仔细检查,并决定如何处理非法输入
断言
exception
特定的错误处理技术
路障
调试辅助工具
2.路障
出于防御编程目的设置路障的一种方法是将某些接口指定为“安全”区域的边界。检查跨越安全区域边界的数据的有效性,如果数据无效,则做出明智的响应。
1.类的public方法接收到的外部数据都应被认为是dirty的,需要处理干净再传递到private方法——隔离舱
2.另一种方法是操作间技术 – 数据在进入操作间之前已消毒。操作间里的任何东西都被认为是安全的。
路障的使用将断言和错误处理区分开来。
路障之外的例程应该使用错误处理,因为对数据进行任何假设都是不安全的。
on。
开发阶段用断言尽可能消除bugs,在发行版本里用异常处理机制处理漏掉的错误
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91513 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!