异常与自定义异常【Java】

36 篇文章 0 订阅

异常

什么是异常

异常:即程序执行过程中不正常的行为;
java中不同类型的异常,都有与其对应的类来进行描述

异常的体系结构

  • 异常体系的顶层类是Throwable,顶层类派生出2个子类,即Error(错误)、Exception(异常);
  • 错误是指java虚拟机无法解决的严重问题,但凡发生,没有办法挽回;
  • 异常发生后,程序员是可以通过代码进行处理的;

异常的分类

异常分为编译时异常和运行时异常2种;
编译时异常:也称为受查异常,是在程序编译期间出现的异常;
运行时异常:也称为非受查异常,是在程序执行期间发生的异常;

注:程序编译时出现的语法错误不属于异常,例如一些分号的缺失,括号不匹配等问题;

异常的处理方式

防御式

  • 事前防御型:在操作进行之前进行检查;

在这里插入图片描述

这种处理方式将正确的执行流程和处理错误的流程放在一起,较为混乱,不太推荐;

  • 事后认错型:先进行正常的操作,当程序出现了问题以后再去处理;

在这里插入图片描述
这种处理方式很好的区分了正确的流程和处理错误的流程,代码清晰明了,更为实用;

异常抛出

public static void func(int [] arr,int i) {
        if(i<0||i>arr.length){
            //使用throw来抛出一个异常
            throw new ArrayIndexOutOfBoundsException("数组越界异常");
        }
    }
    public static void main(String[] args) {

        int [] arr={1,2,3,4,5};
        int i=0;
        func(arr,10);


    }
  • java中使用关键字throw来抛出一个异常,一旦throw语句执行,表示一定是出现了此异常;
  • throw语句必须在方法内部;
  • throw语句一次只能抛出一个异常;
  • 异常一旦抛出,throw语句后面的代码不会执行;

异常声明

public static void func(int [] arr,int i) throws ArrayIndexOutOfBoundsException,NullPointerException{//使用throws来声明一个异常
        if(i<0||i>arr.length){
            //使用throw来抛出一个异常
            throw new ArrayIndexOutOfBoundsException("数组越界异常");
            //System.out.println("出现异常时,throw语句后面的代码不会执行");

        }
    }
    public static void main(String[] args) {

        int [] arr={1,2,3,4,5};
        int i=0;
        func(arr,2);


    }
  • 异常的声明需要使用关键字throws;
  • 异常的声明是在方法参数列表的后面,不在方法内部;
  • 可以一次声明多个异常,使用逗号隔开即可;
  • 异常的声明只是提出了一个可能的异常情况,具体是否存在异常不由异常的声明决定;

如果方法内部抛出了多个异常,方法就必须声明多个异常,当抛出的异常之间是父类与子类的关系,则方法可以仅声明父类的异常;
当程序调用抛出异常的方法时,调用者需要对异常进行处理,或者使用throws继续声明;

抛出异常和声明异常都没有对异常真正处理,只是将异常告诉了方法的调用者,如果需要真正对方法进行处理,需要使用 try - catch 进行不活并处理;

异常的捕获处理

public class Test1 {

    public static void func(int [] arr,int i) throws ArrayIndexOutOfBoundsException{//使用throws来声明一个异常

        try{
            if(i<0||i>arr.length){
                //使用throw来抛出一个异常
                throw new ArrayIndexOutOfBoundsException("数组越界异常");
                //System.out.println("出现异常时,throw语句后面的代码不会执行");

            }
        }catch(ArrayIndexOutOfBoundsException e ){
            e.printStackTrace();//使用该语句可以让我们看到异常的情况
            System.out.println("");
        }

    }
    public static void main(String[] args)  {

        int [] arr={1,2,3,4,5};
        int i=0;
        func(arr,6);


    }
}

在这里插入图片描述这里通过程序的退出码为0得知,程序是正常且成功执行完毕的,标红的异常是由于使用了printStackTrace( )方法;

使用try - catch 成功捕获并处理异常的条件:
异常的类型与 catch ( 异常 e)的异常必须一致或是前者是后者的基类;
异常是根据类型来捕获的;

public class Test1 {

    public static void func(int [] arr,int i) {

        try{
            if(i<0||i>arr.length){
                //使用throw来抛出一个异常
                throw new ArrayIndexOutOfBoundsException("数组越界异常");
                //try块内抛出异常位置之后的代码将不会被执行


            }
        }catch(ArrayIndexOutOfBoundsException e ){
            e.printStackTrace();//使用该语句可以让我们看到异常的情况
            System.out.println("处理异常");
            //异常处理成功这里的后续代码都可以执行;
        }

    }
    public static void main(String[] args) throws ArrayIndexOutOfBoundsException {

        int [] arr={1,2,3,4,5};
        int i=0;
        func(arr,6);


    }
}

在这里插入图片描述多种异常,一次捕获,多次处理:

public static void main(String[] args) {
        int [] arr={1,2,3,4,5};
        int [] arr1=null;
        try{
            System.out.println(arr[5]);

            System.out.println(arr1[2]);
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("数组越界异常");
            e.printStackTrace();
        }catch (NullPointerException e){
            System.out.println("空指针异常");
            e.printStackTrace();
        }
    }

在这里插入图片描述

这里try当中有多个异常,捕获的时候可以捕获多个异常,但是第一个异常之后,后面的代码不会再运行了,因此结果显示只捕获到了一个异常;

如果多个异常的处理方式相同,可以进行合并:

catch(ArrayIndexOutOfBoundsException | NullPointerException e){

}

如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则会出错;

在这里插入图片描述
可以通过一个catch(Exception e)捕获所有的异常,即多个异常,一次捕获;但并不推荐,因为这种方式不利于后续针对特定的异常进行特定的处理,但可以使用catch(Exception e)来进行保底捕获,避免有遗漏的异常未成功捕获;

finally

异常的产生可能使一些语句不被执行到,但真正在程序的运行过程中,有些特定的代码不论在什么情况下都需要被执行,因此需要finally来解决这个问题;

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        try {

            System.out.println(arr[5]);

        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("这是个数组下标越界异常");
            e.printStackTrace();
        } finally {
            System.out.println("这里的代码永远都会被执行");
        }
        System.out.println("没有异常抛出或者异常被成功处理,这里的代码就会执行");
    }

在这里插入图片描述

自定义异常

自定义异常的流程:

  • 自定义异常类,继承Exception或者RuntimeException;
  • 在自定义的异常类中定义带一个string参数的构造方法;
  • 在合适的位置声明和抛出异常;
public class LogIn {
    private String userName = "hello";
    private String password = "123456";
    public static void main(String[] args) {
        try{
            LogIn login=new LogIn();
            login.loginInfo("asd", "123456");
        }catch (userNameException e){
            e.printStackTrace();
            System.out.println("用户名错误");
        }catch (passwordException e){
            e.printStackTrace();
            System.out.println("密码错误");
        }

    }
//自定义异常类,需要继承
    class userNameException extends Exception{
        public userNameException(String message) {
            super(message);
        }
    }

    class passwordException extends Exception{
        public passwordException(String message) {
            super(message);
        }
    }
    
    //进行异常的声明和抛出
    public void loginInfo(String userName, String password) throws userNameException,passwordException{
        if (!this.userName.equals(userName)) {
            throw new userNameException("用户名错误异常");

        }
        if (!this.password.equals(password)) {
            throw new passwordException("密码错误异常");

        }
        System.out.println("登陆成功");
    }
}

在这里插入图片描述

注:继承自 Exception 的异常默认是受查异常;
继承自 RuntimeException 的异常默认是非受查异常;

over !

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值