Java基础第二遍-09-面向对象-异常

简介

  1. Java中用类的形式对不正常情况进行了描述和封装对象
  2. 描述不正常情况的类就称为异常类
  3. 在有专门的异常类之前,正常流程代码和问题处理代码相结合
  4. 在有异常类之后,将正常流程代码与问题处理代码进行分离,提高阅读性
  5. 异常:就是Java通过面向对象的思想将问题封装成了一个对象,用异常类(Throwable异常类的祖宗类)对其进行描述,不同的问题使用不同的类进行描述
  6. Throwable下有两个子类,无论是Error还是Exception 都是程序运行过程中的问题,都需要通知调用者,所以需要抛出
    1. Error:描述不可解决问题,一般是由JVM抛出的严重性问题,解决方案,修改程序
    2. Exception:可处理问题
  7. Throwable的及其所有的子类都具有可抛性,凡是具有可抛性的类或对象都可以被throw、throws操作,同理被他们操作的都具有可抛性。

异常的分类-及异常的声明

  1. 编译时被检测异常:只要是Exception和其子类都是,除了特殊类RuntimeException类
    1. 编译时检测是为了希望,这种问题尽早的进行处理
  2. 编译时不检测异常(运行时异常):就是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();//此异常类为运行时检测异常类,不进行声明
    }
}
  1. 为什么进行异常的声明?
    1. 是为了对异常进行处理try{}catch(){}finally{}
  2. 总结:
    1. 所以自定义异常要么继承Exception、或者RuntimeException

异常处理的捕获

  1. 格式:try{}catch(){}finally{}
  2. 执行流程:image
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的异常打印机制调用的也是这个方法
        }

    }
}
  1. 如果抛出多个异常,需要使用多个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){//爷爷类
        }

异常的抛出流程

image

  1. 异常抛出throw
    image
  2. 异常抛出throws

自定义异常

  1. 命名特点:xxxxException、xxxxError

异常处理的规则

  1. 函数内容如果抛出需要检测的异常,那么函数上必须要声明(throws),否则在函数内部使用try{}catch(){}捕捉,否则编译失败
  2. 如果调用了声明异常的函数,要么try{}catch(){},要么throws,否则编译失败
  3. 什么时候使用catch、什么时候使用throws?
    1. 如果可以处理就用catch
    2. 不能处理,就用throws抛出异常,给调用者处理(try{}catch(){})
  4. 一个功能如果抛出多个异常,那么就需要catch几个异常,且按子类 父类依次捕获

finally

  1. finally{}中的语句只要程序能够正常运行,最终都会被执行(return、System.exit(0);会提前结束程序,finally不会被执行)
  2. 作用:一般用于释放资源(IO资源、数据库连接资源等)

try catch finally的组合使用

  1. try{}catch(){};没有什么资源需要关闭的时候,可以不使用finally
  2. try{}catch(){}finally{};有资源需要关闭的时候,使用finally
  3. try{}finally{};用于开启了资源,后程序异常了,但是不能处理,然而资源需要关闭,可以用这种组合形式

异常转换

  1. image
    捕获了一个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失败,关闭资源");
        }
    }
}

异常注意事项

  1. 子类在覆盖父类方法时,如果父类的方法抛出了异常,那么子类的方法只能抛出父类的异常,或者该异常的子类
  2. 如果父类方法抛出多个异常,那么子类只能抛出父类异常的子集
  3. 如果父类的方法没有抛出异常,那么子类覆盖该方法时绝对不能抛出异常,只能try{}
posted @ 2021-10-27 19:08  争取做百分之一  阅读(47)  评论(0)    收藏  举报