异常

概述

  • 异常本身是一个类,产生异常就是创建一个异常对象并抛出一个异常对象。java处理异常的方式是中断处理。
  • 异常不是语法错误,语法错了,编译不能通过;

异常体系

  • 异常的根类是:java.lang.Throwable
  • 其下有两个子类:java.lang.Error 和 java.lang.Exception
  • Error:严重错误,无法处理,只能尽量避免,好比绝症
  • Exception:表示异常,异常产生后程序员可以通过代码纠正,使程序继续运行,必须要处理的,好比感冒
    编译期异常:进行编译(写代码)java程序出现的问题
    运行时异常:运行期异常,java程序运行过程中出现的问题

异常的产生过程

异常产生过程解析

异常的处理

抛出异常throw

  • 作用:可以使用throw关键字在指定方法中抛出指定的异常
  • 使用格式:throw new xxxException(“异常产生的原因”)
  • 注意:
    1)throw关键字必须写在方法的内部
    2)throw关键字后边new的对象必须是Exception或Exception的子类对象
    3)throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
    throw关键字后边创建的是RuntimeException或RuntimeException的子类对象,我们可以不处理,默认交给JVM处理(打印异常对象,中断程序)
    throw关键字后边创建的是编译异常(写代码的时候报错),我们就必须处理这个异常,要么throws,要么try…catch
public class throw_test {
    public static void main(String[] args) {
        //抛出空指针异常
        int[] arr=null;
        //抛出数组越界异常
        arr=new int[]{1,2};
        int e=getElement(arr,3);
    }

    private static int getElement(int[] arr,int index) {
        if(arr == null)
            throw new NullPointerException("数组长度为0");
        if(index<0 || index>=arr.length)
            throw new ArrayIndexOutOfBoundsException("索引越界");
        return arr[index];
    }
}

Objects非空判断

  • java.util.Objects类是由一些静态方法组成的,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),那么在它的源码中,对对象的null值进行了抛出异常的操作。
  • public static T requireNonNull(T obj):查看指定引用对象不是null
    源码

声明异常throws

  • 异常处理的第一种方式,交给别人处理
  • 作用:当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象;
    可以使用throws关键字处理异常对象,会把异常对象声明抛出给方法的调用者处理(方法自己不处理,交给别人处理),最终交给JVM处理–>中断处理;
  • 使用格式:在方法声明时使用
    修饰符 返回值类型 方法名(参数列表)throws AAAExceptions,BBBException{
    throw new AAAException(“AAA”);
    throw new BBBException(“BBB”);
    }
  • 注意:
    1)方法内部如果抛出了多个异常对象,throws后边也必须声明多个异常
    如果抛出的异常有子父类关系,那么直接声明父类异常即可
    2)调用了一个声明抛出异常的方法,我们就必须处理声明的异常,要么throws继续抛出,要么try…catch自己处理;
public class throws_test {
    public static void main(String[] args) throws FileNotFoundException {//继续抛出异常给JVM
        readfile("C:\\a.txt");
    }
    /*
    如果传递的文件路径不是"C:\\a.txt",则抛出文件找不到异常
    FileNotFoundException不是RuntimeException的子类,所以必须处理
     */
    private static void readfile(String filename) throws FileNotFoundException {
        if(!filename.equals("C:\\a.txt")){
            throw new FileNotFoundException("文件没找到");
        }
    }
}

捕获异常try…catch

  • 异常处理的第二种方式,自己处理异常
  • 格式:
    try{
    可能产生异常的代码
    }catch(定义一个异常变量,接收try中抛出的异常){
    异常处理逻辑
    一般在工作中,会把异常记录到日志中
    }
  • 注意
    1)用throws方法抛出异常后,异常之后的代码不会执行,而用try…catch执行完异常处理后,会继续执行catch后续代码,但try中出现异常后的代码也无法执行了;
public class trycatch {
    public static void main(String[] args) {
        try {
            readfile("d");
            System.out.println("异常发生后不可以执行");//这条程序没有执行
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("处理完异常后可以执行");//这条程序执行了
    }
    /*
   如果传递的文件路径不是"C:\\a.txt",则抛出文件找不到异常
    */
    private static void readfile(String filename) throws FileNotFoundException {
        if(!filename.equals("C:\\a.txt")){
            throw new FileNotFoundException("文件没找到");
        }
        System.out.println("异常发生后无法执行");//这条程序没有执行
    }
}

如何获取异常信息

获取异常信息的方法

finally代码块

  • 作用:有些特定的代码,无论是否发生异常,都需要执行。另外,异常会引发程序跳转,导致有些语句执行不到,而finally就是解决这个问题的;
  • 格式:try…catch…finally
  • 注意:
    1)无论是否发生异常,finally中的代码都会执行;
    2)finally不能单独使用,必须和try一起使用;
    3)finally一般用于资源回收

异常的注意事项

  • 多个异常分别处理:每个异常都对应一个try…catch
  • 多个异常一次捕获多次处理:多个异常都放在一个try中,但每个异常都对应一个catch,注意,catch中的异常子异常先catch父异常后catch
  • 多个异常一次捕获一次处理:多个异常都放在一个try中,但只有一个catch,catch中的异常是所有抛出异常的父类
  • 运行时异常被抛出可以不处理,即不捕获也不抛出;
  • 如果finally有return语句,永远返回finally中的结果,避免该情况;
public class finally_test {
    public static void main(String[] args) {
        int a =getA();//a=100,永远返回finally中的值
    }
    private static int getA() {
        int a=10;
        try {
            return a;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            a = 100;
            return a;
        }
    }
}
  • 如果父类抛出多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类的子类或者不抛出异常
  • 父类方法没有抛出异常,子类重写父类方法时也不能抛出异常,此时子类产生该异常,只能捕获处理,不能声明抛出;(父类异常是什么样,子类异常就是什么样)

自定义异常

  • 格式:
    public class xxxException extends Exception | RuntimeException{
    添加一个空参数的构造方法;
    添加一个带异常信息的构造方法;
    }

  • 注意:
    1)自定义异常类都是以Exception结尾,说明该类是一个异常类;
    2)自定义异常类必须继承Exception或RuntimeException类
    继承Exception:那么自定义的异常类就是一个编译期异常,如果方法内部抛出了编译器异常,就必须处理这个异常;
    继承RuntimeException:那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理

public class RegisterException extends Exception {
    //添加一个空参数的构造方法
    public RegisterException(){
        super();
    }
  //添加一个带异常信息的构造方法
  //通过源码看到,所有异常类都会有一个带异常信息的构造方法,方法内部调用父类带异常信息的构造方法
    public RegisterException(String message){
        super(message);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值