第七章 异常 断言 日志
异常
异常分类
- 异常对象都是派生于Throwable类的实例
- Thorwable下一层分解为Error 和Exception两个分支,Error描述运行时系统内部错误和资源耗尽错误。应用程序不该抛出这种类型的对象。Exceptionc错误分两个分支:RuntimeException(程序本身错误)和IOException(I/O错误)。
- 派生于RuntimeException的异常包含下面的几种情况:
- 错误类型转换
- 数组访问越界
- 访问null指针
- 检测数组下标是否越界来避免ArrayIndexOutOfBoundsException
- 在使用变量之前检测是否为null来避免NullPointerException。
声明受查异常
什么是非受查异常。
派生于Error类或者RuntimeException类的所有异常成为非受查异常。
方法应该在其首部声明所有可能抛出的异常。什么情况下抛出异常?
- 调用一个抛出受查异常的方法
- 程序运行过程中出现错误,并用throw语句抛出一个受查异常
- 程序出现错误
- java虚拟机运行时出现的库内部错误
除了声明异常之外,还可以捕获异常,这样会使异常不被抛出到方法之外。
如何抛出异常?
一旦方法抛出了异常,这个方法就不能返回到调用者了。
也就是说,不必为返回的默认值或错误代码担忧。
如何创建异常类??
或者定义一个派生于Exception的类
或者定义一个派生于Exception的子类的类
- 定义的类包含两个构造器,一个默认的构造器,一个带有详细描述信息的构造器
一个栗子:
class FileFormatException extends IOException
{
public FileFormatException(){}
public FielFormatException(String gripe){
super(gripe);
}
}
//The method to use that Exception
if(len>n){
throw new FileFormatException();
}
捕获异常
如何捕获异常
使用try catch语句即可。
编译器严格执行throws说明符,如果调用了一个抛出受查异常的方法,就必须对它进行处理,或者继续传递。
如何更好?
通常应该捕获那些知道如何处理的异常,而将那些不知道如何处理的异常继续传递。
如何捕获多个异常?
e.getMessage和e.getClass().getName()可以得到异常对象的实际类型。
finally子句:
应用场景:当发生异常时,恰当关闭数据库的连接是非常重要的。
无论try语句块中是否遇到异常,finally子句的in.close()语句都会被执行。强烈建议耦合try/catch 和try/finally语句块。这样可以提高代码清晰度。
注意,如果在finally块中写return语句会覆盖原来的正常返回值。如果在finally块中的代码如果抛出异常会覆盖原始捕获到的异常。这就成了问题。
带资源的try语句
在try块退出时候,自动关闭资源的一个典型例子:
try(Scanner in=new Scanner(new FileInputStream("/home/t.txt")),"UTF-8")
{
while(in.hasNext())
System.out.print(in.next());
}
当这个快正常退出,或者存在一个异常时,都会调用in.close()方法,就好像使用了finally块一样。
这个例子是非常有用的。
异常机制的使用技巧
- 异常处理不可以代替简单的测试
- 不要过分细化异常
- 利用异常的层次结构
- 不要压制异常
- 检测错误时,苛刻比放任好
- 不要羞于传递异常
断言(用于测试)
干什么的?
断言机制允许在测试期间向代码中插入一些检查语句。当代码发布的时候,这些插入的语句会自动被移走。
关键字assert 条件:
assert 条件:表达式;表达式被传入AssertException的构造器,并转换成一个消息字符串。
一个栗子:
assert x>=0;
assert x>=0:x;
如何启用和禁用断言?P286
断言 参数检查
断言只用于在测试阶段确定程序内部的错误位置。
日志
日志记录是一种可以在程序整个生命周期使用的策略性工具。
2018年11月30日 16:54:27
基本日志
Logger.getGlobal().info("hhh ")
高级日志
不将所有日志写到一个全局日志记录器中
private static final Logger myLogger=Logger.getLogger("com.company.myapp")
这样来创建或获取日志记录器。防止被当做垃圾回收,这里使用一个静态变量存储日志记录器的引用。
注意,日志记录器也是有层次结构的。