学到这里,大家也知道,Java的基础语法已经学完了,异常将是我们在Java深入篇中遇到的第一个难关。
至于什么是异常,大家或许都遇到过这种情况,在玩游戏的时候,游戏有时会无端的崩溃掉,不单单是游戏,windows系统在早期时也经常蓝屏,有时候也提交各种错误报告,告诉你程序哪里有问题了,要重启。你按下确定键后,他就帮你重新启动,你要是按了其他,他就直接退出了。没有什么程序是不会出问题的,作为开发者,我们应该做的就是尽力去避免出现bug,以免影响用户对软件的体验度。同时,一旦出现了错误,我们也应该尽快去进行修复,而基于这一原则,就诞生我们今天的主角——java的异常处理。
异常的分类
异常处理是基于面向对象而实现的,也即是说java把大部分可能存在的异常信息都封装成一个个对应的类了。当然,我们也可以在原有类的基础上进行拓展。这就涉及了异常处理机制的体系结构。
Throwable类中有两个直接子类Error类和exception类。
Error : 指合理的应用程序在执行过程中发生的严重问题。当程序发生这种严重错误时,通常的做法是通知用户并中止程序的执行。
Exception:异常可分为运行时异常(RuntimeException)和检查时异常(CheckedException)两种:
1、RuntimeException:运行时异常,即程序运行时抛出的异常。这种异常在写代码时不进行处理,Java源文件也能编译通过。 RuntimeException异常类及其下面的子类均为运行时异常。
2、CheckedException:检查时异常,又称为非运行时异常,这样的异常必须在编程时进行处理,否则就会编译不通过。Exception异常类及其子类(除去RuntimeException异常类及其子类)都是检查时异常。
常见异常:
异常名 | 说明 |
Exception | 异常类的根类 |
RuntimeException | 运行时异常类的基类 |
ArithmeticException | 算术错误情形,如以零作除数 |
ArrayIndexOutOfBoundException | 数组大小小于或大于实际的数组大小 |
NullPointerException | 尝试访问 null 对象成员 |
ClassNotFoundException | 不能加载所需的类 |
NumberFormatException | 数字转化格式异常,字符串到 float 转换无效 |
IOException | I/O 异常的根类 |
FileNotFoundException | 找不到文件 |
SQLException | 数据库访问异常 |
InterruptedException | 线程被中断异常 |
Java中对异常的处理有如下两种方式:
通过try、catch和finally关键字捕获异常;
通过throw或throws关键字抛出异常。
捕获异常:
try{
//可能抛出异常的语句块
}catch(SomeException1 e){ // SomeException1特指某些异常
//当捕获到SomeException1类型的异常时执行的语句块
} catch( SomeException2 e){
//当捕获到SomeException2类型的异常时执行的语句块
}finally{
//无论是否发生异常都会执行的代码
}
try…catch…finally异常处理结构中,try语句块是必须的, catch和finally语句块至少出现一个。
注意:如果try语句块包含的是检查时异常,则在没有通过throws抛出该异常类的情况下,try必须和catch一起使用,当该行代码去掉或注销掉时,catch相应的异常语句块必须去掉,如下代码:
public class Test {
public static void main(String[] args) {
try {
Class.forName("java.lang.Object");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
由于该行代码抛出检查时异常,所以该行代码去掉或注销掉时,catch相应的异常语句块必须去掉。
try语句块中的代码可能会引发多种类型的异常,当引发异常时,会按顺序查看每个 catch 语句,并执行第一个与异常类型匹配的catch语句,其后 catch 语句被忽略。
在捕获异常的时候,应按照“从小到大”的顺序捕获异常,即先子类后父类。
Java异常在try/catch块后加入finally块,可以确保无论是否发生异常 finally块中的代码总能被执行。
抛出异常:
throw用于抛出具体异常类的对象,一般用于方法体中。
什么时候使用:当所写的代码因不满足某些条件致使程序无法运行时可以借助throw抛出一个异常对象提醒程序员。
throw关键字一般用在方法体中,也可以用在代码块中,但如果代码块中抛出的异常对象是由检查时异常创建的,则必须使用try-catch进行处理。
throw关键字:
throws用于声明方法可能抛出的异常,其后为异常类,可以有多个,异常类之间用英文逗号间隔。
什么时候使用:
当方法体中的throw关键字抛出由检查时异常创建的对象时,如果该异常对象在抛出的同时已经通过try-catch进行了处理,则可以不使用throws,否则必须使用throws抛出创建该对象的异常类或其父类。
所调用的方法抛出了检查时异常时,如果该方法在调用的同时已经通过try-catch进行了处理,则可以不使用throws继续上抛该异常,否则必须使用throws才能上抛该异常,此时上抛的异常类可以是调用方法时方法抛出的异常类也可以是其父类。
public class Test {
public static void main(String[] args) throws NoSuchBeanDefinitionException {
System.out.println(Application.getBean(Tiger.class));
}
}
这个getBean方法中抛出了一个NoSuchBeanDefinitionException异常,若在此不处理,则抛出去。