文章目录
一、异常概述
1. 异常的定义
• Java语言将程序运行过程中所发生的不正常严重错误称为异常,对异常的处理称为异常处理。
• 它会中断正在运行的程序,正因为如此异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点。
2. 异常分类
Throwable有两个直接子类,Error类和Exception类。
- Error : 指合理的应用程序在执行过程中发生的严重问题。当程序发生这种严重错误时,通常的做法是通知用户并中止程序的执行。
- Exception:异常可分为运行时异常(RuntimeException)和检查时异常(CheckedException)两种:
- RuntimeException:运行时异常,即程序运行时抛出的异常。这种异常在写代码时不进行处理,Java源文件也能编译通过。 RuntimeException异常类及其下面的子类均为运行时异常。
- CheckedException:检查时异常,又称为非运行时异常,这样的异常必须在编程时进行处理,否则就会编译不通过。Exception异常类及其子类(除去RuntimeException异常类及其子类)都是检查时异常。
3. 常见异常
4. 处理异常
- Java中对异常的处理有如下两种方式:
- 通过try、catch和finally关键字捕获异常;
- 通过throw或throws关键字抛出异常;
二、捕获异常
1. 捕获异常语法结构
try{
//可能抛出异常的语句块
}catch(SomeException1 e){ // SomeException1特指某些异常
//当捕获到SomeException1类型的异常时执行的语句块
} catch( SomeException2 e){
//当捕获到SomeException2类型的异常时执行的语句块
}finally{
//无论是否发生异常都会执行的代码
}
- try…catch…finally异常处理结构中,try语句块是必须的, catch和finally语句块至少出现一个。
注意: 如果try语句块包含的是检查时异常,则在没有通过throws抛出该异常类的情况下,try必须和catch一起使用,当该行代码去掉或注销掉时,catch相应的异常语句块必须去掉。
多重catch
-
try语句块中的代码可能会引发多种类型的异常,当引发异常时,会按顺序查看每个 catch 语句,并执行第一个与异常类型匹配的catch语句,其后 catch 语句被忽略。
-
在捕获异常的时候,应按照“从小到大”的顺序捕获异常,即先子类后父类。
3. finally关键字
- Java异常在try/catch块后加入finally块,可以确保无论是否发生异常 finally块中的代码总能被执行。
4. final、finally和finalize区别
- final—修饰符(关键字),修饰的类不能被继承,修饰的方法不能被重写,修饰的变量为常量。
- finally—在异常处理时提供 finally 块来执行任何清除操作。
- finalize—方法名,finalize() 方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。
三、抛出异常
1. throw关键字
- throw用于抛出具体异常类的对象,一般用于方法体中。
- 什么时候使用:当所写的代码因不满足某些条件致使程序无法运行时可以借助throw抛出一个异常对象提醒程序员。
- throw关键字一般用在方法体中,也可以用在代码块中,但如果代码块中抛出的异常对象是由检查时异常创建的,则必须使用try-catch进行处理;
- throw将异常对象抛给谁
-
抛给自己
-
抛给方法调用者
仅仅使用throw关键字将异常对象抛出,此处没做任何处理;如果抛出的异常类对象是由检查时异常类创建的,则还需要使用throws抛出抛出创建该异常对象的异常类或其父类
- 处理方式一:方法调用者使用try-catch处理该异常(推荐)
- 处理方式二:方法调用者继续上抛该异常,由于方法抛出的是运行时异常类创建的对象,所以可以如下这样做;如果抛出由检查时异常类创建的对象,则这种处理方式必须使用throws关键字抛出创建该对象的异常类或其父类
- 处理方式一:方法调用者使用try-catch处理该异常(推荐)
-
2. throws关键字
-
throws用于声明方法可能抛出的异常,其后为异常类,可以有多个,异常类之间用英文逗号间隔。
-
什么时候使用:
- 当方法体中的throw关键字抛出由检查时异常创建的对象时,如果该异常对象在抛出的同时已经通过try-catch进行了处理,则可以不使用throws,否则必须使用throws抛出创建该对象的异常类或其父类。
- 所调用的方法抛出了检查时异常时,如果该方法在调用的同时已经通过try-catch进行了处理,则可以不使用throws继续上抛该异常,否则必须使用throws才能上抛该异常,此时上抛的异常类可以是调用方法时方法抛出的异常类也可以是其父类。
-
如果方法中的异常已经通过try-catch进行了捕获则无需再使用throws上抛该异常了,否则即使上抛也无效,只会做无用功。
-
如果方法中的代码或者方法中所调用的代码没有使用throw抛出异常类对象,则无需使用throws否则该throws所抛出的异常类无效:即使用throws则其方法中的代码一定存在使用throw抛出异常对象的代码。
3. throw与throws的区别
- 抛出的东西不同:throw抛出的是具体的异常对象,而throws抛出的是抽象的异常类;
- 使用位置不同:throw一般用在方法体中,也可用在代码块中,但是如果抛出的是检查时异常类创建的对象,则必须使用try-catch自行处理;throws只能用在方法声明括号后面;
四、自定义异常类
-
为什么?
- Java API提供的已有异常类无法准确表述当前发生的异常问题,这时就需要创建自定义的异常。
-
怎么做?
- 创建继承Exception 或其子类的自定义类;
- 自定义异常类调用父类构造函数(通常是含有一个String类型参数的构造函数);