什么是异常?异常可以看作你敲出来的bug


作为初学者,在刚开始写代码的时候,差不多写一行代码都要见一行红吧
在这里插入图片描述

异常的体系

在这里插入图片描述
这里我们首先需要知道的一点是,所有的异常其实都是类。我们所有的异常都是继承于Throwable这个大类的,然后当我们的程序导致了内存的耗尽之类的我们程序猿无能为力的异常的时候就会发生Error这类。
我们能够操作的,在这篇博客中我想教给大家的是第二类,我们可以通过技术手段来解决这类的异常,也就是Exception类。
有的时候啊我们的程序还没有运行,下面就要有波浪线了,这就叫做编译异常,也叫做受查异常。比如:
在这里插入图片描述
然后像数组越界异常就是运行时异常,只有程序跑起来了,才知道到底有没有出错。

抛异常

我们都知道抛异常抛异常,但是到底什么是抛异常,我们又该如何抛异常呢?
阿涛这就来给兄弟们演示一下:

    public static void set(int[]arr,int index){
        arr[index]=index;
    }
    public static void main(String[] args)throws ArrayIndexOutOfBoundsException {
        int[]arr=null;
        set(arr,2);

在这里插入图片描述
红字的第一行会告诉你异常的类型,然后下面会告诉你出现异常的具体位置,
在这里插入图片描述
我们应该知道函数是压栈,这里抛异常一般会沿着函数栈帧往上,所以我们只要解决了第一个出现的异常那么后面基本上也就可以解决了。
那么我们现在来抛异常:
在这里插入图片描述
我们要在方法的参数列表后面加上throws 一个异常的类型,然后在方法中要throw一个new出来的异常对象。
我们可以看到的是,第十九行的打印并没有出现,所以一旦程序抛出了异常,后面的代码都是不会执行的。
我们使用throws好像并没有对异常进行实际的处理,连code都是异常的1,仅仅是告诉了后生,这边有个坑,你到时候给我填上去。

try -catch

那么我们想要都异常进行该如何是好呢?
那就需要使用try-catch 对异常进行捕捉了:

    public static void set(int[] arr, int index) throws NullPointerException {
        try {
//            set(arr,2);
//            System.out.println(1111);
            arr[index] = index;
        } catch (NullPointerException e) {
            e.printStackTrace();
            System.out.println("处理了问题");
        }
    }

在这里插入图片描述
我们在try中需要放入可能出现异常的代码,然后catch(异常的类型+变量名){
这中间是对异常代码的处理,可以根据异常的紧急程度来设置,十分紧急就直接掐掉,不是很紧急可以选择给睡大觉的程序猿发上一封邮件打个电话之类的,我们这里水平有限,只能以日志的方式来记载,希望兄弟们不要介意……
}
最后还可以加一个final来做收尾,我们后面讲。
当然了,我们初学者很有可能就在一个try里面写出三行语句,七八个异常,此时此刻我们可不敢赌我们所写的异常就是我们需要捕捉的,这时候我们就需要了解catch可以catch多个异常这个机制了:

        try {
//            set(arr,2);
//            System.out.println(1111);
            arr[index] = index;
        }catch (CloneNotSupportedException e){
            
        }
        catch (ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
            
        } catch (NullPointerException e) {
            e.printStackTrace();
            System.out.println("处理了问题");
        }
    }

在这里我们catch了三个异常,但是似乎出现了一点问题:
在这里插入图片描述
为啥出师不利,第一个就爆红了呢?
对于受查异常来说,抽查异常都是当场发现当场解决的,但是此时我们try里面并没有发现对应的异常,所以说想要捕捉受查异常可要想好了,只有存在受查异常的时候才能进行相应的捕捉!
由于异常也是类,异常也会有很多的继承关系,那么我们只要捕捉一个runtimException从理论上来说就可以捕捉到所有的运行时异常了,但是我们从来不会选择那么做,因为那样做对于当前你写代码来说可能是省了不少事情,但是对于以后的代码优化维护来说你这样会无形之中增加许多不必要的麻烦,该偷的懒Java已经帮我们偷了,有些不能够偷的懒可千万不能啊!!

finally

我们的体系大概是try-catch-finally,finally使用在最后的收尾工作的,关闭资源什么的:

        } catch (NullPointerException e) {
            e.printStackTrace();
            System.out.println("处理了问题");
        }
        finally {
            scanner.close();
        }

或者我们根据编译器的提示可以改成这样:

 try (Scanner scanner = new Scanner(System.in)) {

这样子就不用我们在最后关闭资源了。
这里强调一下,在finally中的代码不管如何一定会实现,而且是最后实现:

    public static int add(int a){
        try {
            return a;
        }catch (RuntimeException e){
            e.printStackTrace();
        }finally {
            return 4;

        }

    }
    public static void main(String[] args) {
        int x=add(10);
        System.out.println(x);

按照我们之前的理解,一个方法只要遇到了return就会返回,我既然说出来了那肯定是有不一样的地方的:
在这里插入图片描述
此时此刻我们返回的并不是try中的return a,而是finally中的return,这就是我们说的finally中的代码一定会被执行,这个机制啊奇怪的很,大家只要知道就行。

自定义异常

难道我们的异常只能是编译器提供给我们的那两三个吗?我们程序猿是一个有着相当的创造力和自由度的群体,我们可以自己写异常:
首先我们要清楚,我们这里写的所有的异常都是继承于Exception的,当然了我们还可以更加具体到这是否是受查异常:

public class LoadException extends RuntimeException{

}

然后我们可以照猫画虎,点进RuntimeException看看里面有没有什么需要我们重写的:
在这里插入图片描述
这里大概就是告诉我们该如何描写错误信息的,我们直接复制粘贴就行:

public class KeyException extends RuntimeException{
    public KeyException() {
        super();
    }
    public KeyException(String message) {
        super(message);
    }

}

然后我们需要在try-catch语句中写好我们判断的逻辑:

    public static void load(String name,String key){
        Test test=new Test();
        try{
            if(!test.name.equals(name)){
                throw new NameException("用户名错误");
            }
            if (!test.key.equals(key)){
                throw new KeyException("密码错误");
            }
        }catch (NameException e){
            e.printStackTrace();
        }catch (KeyException e){
            e.printStackTrace();
        }finally {
            System.out.println("嘤嘤嘤");
        }

    }
    public static void main(String[] args) {
        load("cyt","123");

    }

在这里插入图片描述
此时此刻我们自己捕捉到了我们自己的异常,并且进行了处理,所以此时我们的code是1!
好了兄弟们关于异常大部分知识点都教给大家了,希望大家能够有所收获!
百年大道,你我共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值