Java核心技术11:异常、日志、断言和调试

11.1    处理异常

11.1.1    异常分类

        Java中,异常对象都是派生于Throwable类的一个实例。进而分为Error和Exception。Error描述了Java运行时系统的内部错误和资源耗尽错误,很少出现。主要关注Exception,分为RuntimeException和其他异常。由程序错误导致的异常属于RuntimeException,程序本身没有问题,由于像io错误等导致的属于其他异常。

        派生于RuntimeException的包含:错误的类型转换、数组访问越界、访问空指针。其他异常包含:试图在文件尾部后面读取数据、试图打开一个错误格式的URL、试图根据给定的字符串查找Class对象而类不存在。

11.1.2    声明已检查异常

        方法应该在其首部声明所有可能抛出的异常,如果抛出多个异常,每个异常类之间用逗号隔开。

        public FileInputStream(String name) throws FileNotFoundException{}

        下面4中情况应抛出异常:

        1. 调用一个抛出已检查异常的方法,如FileInputStream的构造器。

        2. 程序运行过程中发现错误,且利用throw语句抛出一个已检查异常。

        3. 程序出现错误。

        4. Java虚拟机和运行时库出现的内部异常。

        也可以捕获异常,这样异常不被抛到方法之外,也不需要throws规范。

11.1.3    如何抛出异常

        1. 找到一个合适的异常类,2. 创建这个类的一个对象, 3. 将对象抛出

        throw new UserException();

11.1.4    创建异常类

        定义一个派生于Exception的类,或者派生于Exception子类的类。习惯上定义两个构造器,一个是默认构造器,一个带有详细描述信息的构造器(超类Throwable的toString将会打印这些详细信息)。

11.2    捕获异常

        如果某个异常发生的时候没有在任何地方进行捕获,程序就会终止执行,并在控制台上打印出异常信息,包括异常的类型和堆栈的内容。

        捕获异常使用try/catch语句块。如果在try语句块中抛出了一个在catch子句中说明的异常类,那么将跳过try语句块的其余代码,直接执行catch子句中的处理器代码。如果抛出了一个catch子句中没有声明的异常类型,那么这个方法就会立刻退出。

        通常,应该捕获那些知道如何处理的异常,将那些不知道如何处理的异常 传递出去(在方法的首部添加throws说明符)。

11.2.1    捕获多个异常

        对不同类型的异常做不同的处理,为每个异常类型使用一个单独的catch子句。

11.2.2    再次抛出异常与异常链

        在catch子句中再次抛出一个异常,就可以改变异常的类型。

        可以将原始异常设置为新异常的诱饵:catch(SQLException e){ Throwable t= new XXXException(); t.initCause(e);throw t;}    当捕获到异常时,可以使用Throwable e=t.getCause();重新得到原始异常。

11.2.3    finally子句

        不管是否有异常被捕获,finally子句中的代码都被执行。可以只有try/finally,而没有catch,此时异常重新抛出。

        try{

        // 1

        code that might throw exceptions

        // 2

        }catch(IOException e){

        // 3

        show error dialog

        // 4

        }finally{

        // 5

        g.dispose();

        }

        // 6

        1. try中没有抛出异常:try中代码全部执行,finally中代码全部执行,程序继续运行。执行顺序:1-2-5-6

        2. try抛出一个catch子句捕获的异常:try中代码中断执行,执行catch中的代码,最后执行finally中代码。

            如果catch没有抛出异常,则catch中代码全部执行,finally后的代码正常运行,执行顺序:1-3-4-5-6。

            如果catch抛出异常,则catch中断执行,finally后的代码也中断执行,执行顺序:1-3-5。

        3. try抛出一个catch没有捕获的异常:try中代码中断执行,catch的代码不执行,finally中代码执行完即终止:1-5。

11.2.4    分析堆栈跟踪元素

        堆栈跟踪(stack trace)是一个方法调用过程的列表。静态方法Thread.getAllStackTrace方法,产生所有线程的堆栈跟踪。

11.3    使用异常机制的建议

        1. 异常处理不能代替简单的测试,只在异常情况下使用异常机制。

        2. 不要过分地细化异常,将整个任务包装在一个try中,转而使用多个catch。

        3. 利用异常层次结构:不要只抛出RuntimeException,应使用更合适的子类。

        4. 不要压制异常:不太明白这个的意思。

        5. 检测错误时,苛刻要不放任更好。

        6. 不要羞于传递异常。

11.4    断言assert

        在一个具有自我保护能力的程序中,断言是一个常用的习语。假设确信某个属性符合要求,并且代码的执行依赖于这个属性。断言允许在测试期间向代码中插入一些检查语句,当代码发布时,这些插入的检测语句将会被自动地移走。

11.4.1    启用和禁用断言

        默认情况下,断言被禁用。

11.4.2    使用断言的建议

        断言失败是致命的、不可恢复的错误。

        断言检查只用于开发和测试阶段。断言只应该用于在测试阶段确定程序内部的错误位置。

11.4.3    为文档使用断言

11.5    记录日志

11.5.1    基本日志

11.5.2    高级日志

11.5.3    修改日志管理器配置

11.5.4    日志本地化

11.5.5    处理器

11.5.6    过滤器

11.5.7    格式化器

11.5.8    日志记录说明

11.6    调试技术

11.6.1    使用控制台窗口

11.6.2    跟踪AWT事件

11.6.3    AWT的Robot类

11.7    使用调试器

        调试器会全速运行程序,直到遇到一个断点为止。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值