整理自《Java 核心技术 卷一》
异常介绍
异常分类
- 异常处理的任务就是将控制权从错误产生的地方转移给能够处理这种情况的错误处理器。
- 一场对象都是派生于Throwable类的一个实例
- 其中,Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误
- 在设计Java程序的时候,需要关注Exception层次结构。这个层次结构又分解为两个分支,一个分支派生于RuntimeException;另一个分支包含其它异常。划分两个分支的规则是:由程序错误导致的异常属于RuntimeException;而程序本身没有问题,犹豫像I/O错误这类问题导致的异常属于其它异常
- 派生于RuntimeException的异常包含下面几种情况:
- 错误的类型转换
- 数组的访问越界
- 访问空指针
不是派生于RuntimeException的异常包括:
- 试图在文件尾部后面读取数据
- 试图打开一个不存在的文件
- 试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在
Rule:“如果出现RuntimeException异常,那么一定就是你的问题”,RuntimeException的出现应该通过规范化编程来避免
重要的定义:Java语言将派生于Error类或者RuntimeException的所有异常称为”未检查异常(unchecked exception)”,其它的成为已检查异常
声明已检查异常
- 在编写Java的时候,只考虑已检查异常
- 每一个可能被别人使用的方法都应该声明所有可能抛出的异常
- 异常声明方式:
class Demo
{
......
public void function(String var) throws IOException
{
......
}
}
- 如果一个方法有可能抛出多个已检查异常,那么久必须在方法的首部列出所有的异常类,每个异常类之间用逗号隔开
抛出异常
- 在java代码中通过关键字throw来抛出异常
String readData(Scanner in) throws EOFException
{
...
while(...)
{
if(in.hasNext()) // EOF encountered
throw new EOFException();
}
...
return s;
}
- 对于一个已经存在的异常类,将其抛出非常容易,通常步骤为:
- 找到一个合适的异常类
- 创建这个类的一个对象
- 将对象抛出
4
捕获异常
- java代码通过try语句来捕获异常,其代码格式为:
try{
code;
more code;
}
catch (ExceptionType e)
{
handler for this Type;
}
- try语句执行的三种情况:
- 如果try语句块中的任何代码抛出了一个在catch自居中说明的异常类,那么程序将会跳过try语句块之后的代码,接着执行catch子句中的处理器代码
- 如果没有发生异常,执行完try语句,然后跳过catch子句
- 如果方法中的任何代码抛出了一个在catch子句中没有声明的异常类型,那么方法会立刻退出
创建异常类
- 当java.lang.Exception中的错误类型不满足需求的时候,需要自己声明异常类,直接上代码
class FileFormatException extends IOException
{
public FileFormatException(){}
public FileFormatException(String gripe){
super(gripe);
}
}
finnaly子句
- finally子句的作用跟C++中的析构器的功用都是一样的,其代码格式举例说明:
InputStream in = new FileInputStream(...);
try
{
// 1
code with might throw Exceptions
}
catch (IOException e)
{
//show exception message
}
catch (NullPointerException e)
{
//show exception message
}
finally
{
in.close();//无论如何都会执行
}
遗留问题
- page476,子类和超类覆盖的问题
- 异常传递
- 捕获多个异常的时候,一场变量隐含为final变量