第七章 异常, 断言和日志
处理错误
- 出现错误时程序应该(1)返回安全状态并允许用户执行一些其他命令; (2)或者允许用户保存所有操作的结果,并以妥善方式退出程序;
- 错误产生的原因:(1)用户输入错误;(2)设备错误;(3)物理限制;(4)代码错误: 有些情况下代码的调用方并不能根据程序的错误返回码进行处理, 这时就需要抛出异常给异常处理器去处理;
- 应用程序不应该抛出Error级别的错误, 出现这种错误一般时JVM或者资源耗尽, 除了通知用户并中止程序外,无法再做更多;
-
Exception
的子类RuntimeException
表示异常时由程序错误导致, 如果出现RuntimeException
异常, 程序员就一定有责任去处理杜绝它. - 派生于
Error
和RuntimeException
的异常被称为unchecked异常, 其他为checked异常. (checked翻译为受查) - 下面四种情况下应该抛出异常: 1. 调用了抛出异常的方法; 2. 程序throw出一个异常; 3. 程序出错; 4. JVM或运行时库报错
- 对于给外部调用的方法, 有义务在方法上声明throws异常(checked)类型, 但不包括
Error
(调用方没能力处理)还有RuntimeException
非受查异常(程序员有义务避免)
捕获异常
- Java7 允许一个catch中捕获多个类型异常, 变量e隐含final修饰的
catch(FileNotFoundException | UnknownHostException e) { . . . }
- 最佳实践: 重新包装的异常使用
Throwable.initCause(e)
可以设置异常的原因 - 强烈建议解耦合使用try/catch和try/finally
try { try { code that might throw exceptions } finally { in.close() ; } } catch (IOException e) { show error message } }
- 接口
AutoCloseable
,Closeable
(继承自AutoCloseable
) , 实现类的方法可以使用try(;){}块实现资源自动回收.即相当于finally中调用接口的close()
方法. 如果close()方法中也抛出异常, 会被增加到原有异常中, 而finally{}则会替换原有异常.
异常处理的技巧
- 异常处理代替不了单元测试
- 不要过分细化异常, 如每行代码分别捕获
- 利用异常层次结构, 如使用更准确的子类,不要都抛出Exception类
- 不要压制异常, 如catch{}空处理罕见不重要的异常
- 检查错误时, 苛刻比放任更好, 在早期抛出异常更合适 早抛出
- 不要羞于传递异常 晚捕获
使用断言
- 断言默认不启用,通过
java -ea AppName
启用, 其时类加载器的功能,不启用则跳过; -ea, -da, -esa分别时启用,禁用,启用系统类断言 - Java中三种处理系统错误的方式1. 抛出异常; 2. 日志 ; 3. 使用断言
- 断言的特征: 1. 断言失败是致命的, 不可恢复的错误; 2.断言检查只用于开发,测试阶段;
- 断言是测试和调试阶段的战术性工具
调试技巧(只列出不常用但可能有用的)
- java -verbose 标志启动JVM可以查看类加载情况
- javac -Xlint <> 可以对一些常见问题进行检查
- jmap工具可以获取一个堆的转储
jmap -dump:format=b,file=dumpFileName processsID
Jhat dumpFileName
- java -Xprof 标记可以跟踪那些代码常被调用的方法并输出到控制台
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Python Flask学习知识点(二)
使用Flask写简单的API 所有API都一样,不限于编程语言,API的难点在于路由(URL)的设计,能否精准的找到资源,而不是在于如何用技术实现。 在上一篇Python Flask学习知识点(一)文章中,记录了如何在试图函数中返回数据。上篇文章说到Flask返回的本质是字符串,通过content-type来控制返回的字符串转换为需要值,那么我们在写API的时候,API一般返回的都是JSON格式的数据,所以在视图函数中要指定content-type为JSON。 @app.route() def search(): result = {"key1": "a", "key2": "b"} return json.dumps(result), 200, {"content-type": "application/json"} 解释上图代码片段: 我们一般通过视图函数中做处理后拿到数据类型为python内置数据类型dict,而Flask要求,返回的结果必须是字符串,所以我们用json.dumps(result)做处理后再返回。 后边指定返回状态码200,和,返回的content-type为JS...
- 下一篇
python-进程池与线程池,协程
一、进程池与线程池 实现并发的手段有两种,多线程和多进程。注:并发是指多个任务看起来是同时运行的。主要是切换+保存状态。 当我们需要执行的并发任务大于cpu的核数时,我们需要知道一个操作系统不能无限的开启进程和线程,通常有几个核就开几个进程,如果进程开启过多,就无法充分利用cpu多核的优势,效率反而会下降。这个时候就引入了进程池线程池的概念。 池的功能就是限制启动的进程数或线程数 concurent.future模块: concurrent.futures模块提供了高度封装的异步调用接口 ProcessPoolExecutor: 进程池,提供异步调用 p = ProcessPoolExecutor(max_works)对于进程池如果不写max_works:默认的是cpu的数目,默认是4个 ThreadPoolExecutor:线程池,提供异步调用 p = ThreadPoolExecutor(max_works)对于线程池如果不写max_works:默认的是cpu的数目*5 补充: 提交任务的两种方式:# 同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker快速安装Oracle11G,搭建oracle11g学习环境