简介
- Java中用类的形式对不正常情况进行了描述和封装对象
- 描述不正常情况的类就称为异常类
- 在有专门的异常类之前,正常流程代码和问题处理代码相结合
- 在有异常类之后,将正常流程代码与问题处理代码进行分离,提高阅读性
- 异常:就是Java通过面向对象的思想将问题封装成了一个对象,用异常类(Throwable异常类的祖宗类)对其进行描述,不同的问题使用不同的类进行描述
- Throwable下有两个子类,无论是Error还是Exception 都是程序运行过程中的问题,都需要通知调用者,所以需要抛出
- Error:描述不可解决问题,一般是由JVM抛出的严重性问题,解决方案,修改程序
- Exception:可处理问题
- Throwable的及其所有的子类都具有可抛性,凡是具有可抛性的类或对象都可以被throw、throws操作,同理被他们操作的都具有可抛性。
异常的分类-及异常的声明
- 编译时被检测异常:只要是Exception和其子类都是,除了特殊类RuntimeException类
- 编译时检测是为了希望,这种问题尽早的进行处理
- 编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。
class MyException extends Exception{//直接继承的是Eception在使用此类的时候需要声明
}
class Test13{
int mothod(int [] arr, int index) {
return arr[index];
}
void test() throws MyException {//声明异常类
throw new MyException();//此异常类为编译检测异常类,需要进行声明
}
}
2. 这种问题的发生更多是调用者使用不当造成的,一般不进行处理,直接编译通过,在运行的时候强制程序,让调用者修改程序
class MyException_2 extends RuntimeException{//直接继承的是RuntimeEception在使用此类的时候不进行声明
}
class Test13_2{
int mothod(int [] arr, int index) {
return arr[index];
}
void test(){
throw new MyException_2();//此异常类为运行时检测异常类,不进行声明
}
}
- 为什么进行异常的声明?
- 是为了对异常进行处理
try{}catch(){}finally{}
- 总结:
- 所以自定义异常要么继承Exception、或者RuntimeException
异常处理的捕获
- 格式:
try{}catch(){}finally{}
- 执行流程:

package com.bixiangdong.oop;
class MyException14 extends RuntimeException{
MyException14(String message){
super(message);
}
}
class Test14{
int method(int[] arr,int index){
if (index<0)
throw new MyException14("下标不能为负数");
return arr[index];
}
}
public class Demo14 {
public static void main(String[] args) {
try{
new Test14().method(new int[]{1,232,5,3,53},-1);
}catch (MyException14 e){
System.out.println(e);
System.out.println(e.toString());//异常处理类中 e是一个对象,应该打印出一个内存地址,
// 但是java对其进行了一系列处理,所以打印出来的是一个消息字符串
e.printStackTrace();//JVM的异常打印机制调用的也是这个方法
}
}
}
- 如果抛出多个异常,需要使用多个catch进行处理,catch(XXException e)其中的xxException需要按照从子类到父类依次往下写
try {
new Test14().method(new int[]{1,232,5,3,53},-1);
}catch (MyException14 e){//儿子类
}catch (RuntimeException e){//爸爸类
}catch (java.lang.Exception e){//爷爷类
}
异常的抛出流程

- 异常抛出throw

- 异常抛出throws
自定义异常
- 命名特点:xxxxException、xxxxError
异常处理的规则
- 函数内容如果抛出需要检测的异常,那么函数上必须要声明(throws),否则在函数内部使用try{}catch(){}捕捉,否则编译失败
- 如果调用了声明异常的函数,要么try{}catch(){},要么throws,否则编译失败
- 什么时候使用catch、什么时候使用throws?
- 如果可以处理就用catch
- 不能处理,就用throws抛出异常,给调用者处理(try{}catch(){})
- 一个功能如果抛出多个异常,那么就需要catch几个异常,且按子类 父类依次捕获
finally
- finally{}中的语句只要程序能够正常运行,最终都会被执行(return、System.exit(0);会提前结束程序,finally不会被执行)
- 作用:一般用于释放资源(IO资源、数据库连接资源等)
try catch finally的组合使用
- try{}catch(){};没有什么资源需要关闭的时候,可以不使用finally
- try{}catch(){}finally{};有资源需要关闭的时候,使用finally
- try{}finally{};用于开启了资源,后程序异常了,但是不能处理,然而资源需要关闭,可以用这种组合形式
异常转换

捕获了一个AddException异常,然后又抛出一个NoAddException的异常,将自己不能处理的问题抛出给别人,进行了一异常的转换
package com.bixiangdong.oop;
class AddException extends Exception{
AddException(String msg){
super(msg);
}
}
class NoAddException extends Exception{
NoAddException(String msg){
super(msg);
}
}
class Test16{
void method(int index) throws AddException {
if (index<0)
throw new AddException("add异常了");
}
}
class Main{
void method() throws NoAddException {
try{
new Test16().method(-1);
}catch (AddException e){
//我捕获到了添加时发生的异常
System.out.println(e);
//但我处理不了
throw new NoAddException("add异常了,没有添加成功,原因:"+e.toString());
//进行异常转换,告诉别人发生异常了,及异常原因
}
}
}
public class Demo16 {
public static void main(String[] args) throws NoAddException {
try{
new Main().method();
}catch (NoAddException e){
System.out.println(e);
System.out.println("add失败,关闭资源");
}
}
}
异常注意事项
- 子类在覆盖父类方法时,如果父类的方法抛出了异常,那么子类的方法只能抛出父类的异常,或者该异常的子类
- 如果父类方法抛出多个异常,那么子类只能抛出父类异常的子集
- 如果父类的方法没有抛出异常,那么子类覆盖该方法时绝对不能抛出异常,只能try{}