JavaSE 基础(十五) 异常

目录

前言

一. 异常的概念

1.运行时异常

2.编译时异常 

 3.异常的体系结构

二. 异常的处理 

1.异常的抛出

2.异常的捕获

2.1 异常声明throws

2.2 try-catch捕获处理

 2.3 finally

面试题

3.异常的处理流程 

4. 自定义异常类

后记


前言

Hi~ 你好! 

欢迎点击我的博客 : )       

这是我的学习总结,希望也能帮助到你

我的博客地址:hi~,我在这里~,欢迎关注哦,

三连不迷路,优质内容持续更新!

一. 异常的概念

在Java中,将程序执行过程中发生的不正常行为叫做异常

1.运行时异常

运行时异常,也称非受查异常 Unchecked Exception

        System.out.println(10/0);//ArithmeticException ——by zero//算数异常

        int[]arr = null;//引用不指向任何的对象
        System.out.println(arr[1]);//NullPointerException 空指针异常
        System.out.println("hello");//抛出异常之后,没有处理异常,后面的内容不能正常打印

        int []arr ={1,2,3};
        System.out.println(arr[10]);//ArrayIndexOutOfBoundsException 数组越界异常  
        运行时异常(非受查异常)

ArithmeticException ——by zero        算数异常

NullPointerException                           空指针异常

ArrayIndexOutOfBoundsException    数组越界异常  

这三者都是运行时异常,也称为(非受查异常)

 抛出异常之后,没有处理异常,后面的内容不能正常打印

在Java中,不同类型的异常,都有对应的类来进行描述

2.编译时异常 

编译时异常,也叫受查异常 Checked Exception

public class Test1 {   
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person1 = (Person) person.clone();// CloneNotSupportedException  编译时异常 (受查异常)区别于语法错误,不一样滴
    }                                           //必须对其进行捕获或声明以便抛出
}//异常就是类
class Person implements Cloneable{//实现Cloneable接口
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();//重写clone
    }
}

 CloneNotSupportedException 必须对其进行捕获或声明以便抛出

继承自extends  Exception

这类异常叫编译时异常 (受查异常)在编译的时候报错

区别于语法书写时的错误,是不一样滴

 3.异常的体系结构

Error 和 Exception 是顶层类的两个子类,一个负责错误,一个负责异常

Error:Java虚拟机无法解决的问题,如JVM内部错误,资源耗尽 eg.StackOverflowError 

Exception: 可以人为代码解决的问题

二. 异常的处理 

异常处理的主要关键字:throw try catch final throws

1.异常的抛出

1.代码自己执行的过程中,触发异常

2.自己手动抛出异常

    public static void main(String[] args) {
        func(null);
//Exception in thread "main" java.lang.NullPointerException
//	at Learn.Test1.func(Test1.java:32)
//	at Learn.Test1.main(Test1.java:26
    }

    public static void func(int[] a) {
        if (a == null) {
            throw new NullPointerException();//手动抛出一个空指针异常
        }
    }

手动抛出空指针异常 ,一般用在自定义异常

1.throw必须写在方法体内部

2.抛出的对象是Exception或它的子类
3.异常一旦抛出,后面的代码将不会执行

2.异常的捕获

2.1 异常声明throws
  public static void main(String[] args) throws CloneNotSupportedException {//传递到main方法,同样声明来处理
        func2(null);
        System.out.println("test");//没有输出
//Exception in thread "main" java.lang.CloneNotSupportedException
//	at Learn.Test1.func2(Test1.java:45)
//	at Learn.Test1.main(Test1.java:38)
    }

    public static void func2 (int[] a) throws CloneNotSupportedException {//在方法后面通过throes声明异常
        if (a == null) {
            throw new CloneNotSupportedException();//受查异常 //在这里中断了
        }
    }
}//异常就是类

class Person implements Cloneable {//实现Cloneable接口

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();//重写clone
    }
}

用throes在方法的后面进行声明,来表面方法内可能存在的异常

同时会随着方法传导到main方法,main方法同样需要进行声明

当前方法不处理异常,提醒方法的调用者处理异常

如果方法内部抛出多个异常,声明时用逗号隔开

当没有代码没有解决这个异常时,就会交给JVM处理,程序奔溃

2.2 try-catch捕获处理
 public static void main(String[] args)  {//传递到main方法,同样声明来处理
        try {
            //存放可能出现异常是代码
            func2(null);
           // func(null);
        }catch (CloneNotSupportedException e){//(异常的类型 变量)
            // 对于受查异常来说,当try当中没有受查异常的时候catch检查不到就会报错
            e.printStackTrace();//打印栈上的信息
            //java.lang.CloneNotSupportedException
            //	at Learn.Test1.func2(Test1.java:55)
            //	at Learn.Test1.main(Test1.java:41)
            System.out.println("捕捉到了CloneNotSupportedException异常,进行处理异常的逻辑");
        }catch (NullPointerException e){
            e.printStackTrace();
            System.out.println("捕捉到了NullPointerException异常");
        }catch (Exception e){
            System.out.println("Exception兜底");
        }
        System.out.println("正常的逻辑");//此时,没有红字报错了,代码正常运行并打印后面的语句
    }

    public static void func2 (int[] a) throws CloneNotSupportedException {//在方法后面通过throes声明异常
        if (a == null) {
            //throw  new NullPointerException();
            throw new CloneNotSupportedException();//受查异常 //在这里中断了
        }
    }

在try中存放可能出现异常是代码

用catch捕获抛出的异常

对于受查异常来说,当try当中没有受查异常的时候catch检查不到就会报错

catch的多个异常如果有继承关系,父类在后

可以把Exception放在最后一个catch进行兜底

当try当中存在多个异常时,从上往下执行
try块抛出异常后,后面的代码不会执行

如果catch中没有捕获到异常的话,将由JVM兜底,程序终止

 2.3 finally

无论有没有异常,有的语句都需要执行,比如网络连接等,需要对资源进行回收,

异常引发的跳转可能会导致某些语句执行不到,这时就需要用到finally

public static void main(String[] args)  {//传递到main方法,同样声明来处理
        Scanner sc = new Scanner(System.in);
        try {
            int i = sc.nextInt();
            int []arr ={1,2,3};
            System.out.println(arr[2]);
            System.out.println("test");
            //存放可能出现异常是代码
            func2(null);
           // func(null);
        }catch (CloneNotSupportedException e){//(异常的类型 变量)
            // 对于受查异常来说,当try当中没有受查异常的时候catch检查不到就会报错
            e.printStackTrace();//打印栈上的信息
            //java.lang.CloneNotSupportedException
            //	at Learn.Test1.func2(Test1.java:55)
            //	at Learn.Test1.main(Test1.java:41)
            System.out.println("捕捉到了CloneNotSupportedException异常,进行处理异常的逻辑");
        }catch (NullPointerException e){
            e.printStackTrace();
            System.out.println("捕捉到了NullPointerException异常");
        }catch (Exception e){
            System.out.println("Exception兜底");
        }
        try {
            func(null);
        }catch (NullPointerException e){
            e.printStackTrace();
            System.out.println("捕捉到了NullPointerException异常");
        }finally {
            sc.close();
            System.out.println("执行finally语句");//不管是否在try中抛出异常,finally都会执行,一般用于资源的释放
        }
        System.out.println("正常的语句");//此时,没有红字报错了,代码正常运行并打印后面的语句
    }
输出结果:

4
3
test
捕捉到了CloneNotSupportedException异常,进行处理异常的逻辑
捕捉到了NullPointerException异常
执行finally语句
正常的语句
java.lang.CloneNotSupportedException
	at Learn.Test1.func2(Test1.java:79)
	at Learn.Test1.main(Test1.java:49)
java.lang.NullPointerException
	at Learn.Test1.func(Test1.java:91)
	at Learn.Test1.main(Test1.java:65)

Process finished with exit code 0

 不管是否在try中抛出异常,finally都会执行,一般用于资源的释放

 不建议在finally当中写return

面试题

1.throw和throws的区别是什么?

        throw抛出异常,throws声明异常 

2.finally当中的语句一定会执行吗?

        一定会执行

3.异常的处理流程 

如果本方法中没有合适的处理异常的方式,会沿着调用栈向上传递

那么,什么是调用栈呢?
方法之间是存在相互调用关系。 " 调用栈 " 来描述 . JVM 中有一块内存空间称为 "虚拟机栈 " 专门存储方法之间的调用关系 . 当代码中出现异常的时候 , 我们就可以使用 e.printStackTrace(); 的方式查看出现异常代码的调用栈

 异常处理流程:

 1.程序先执行try当中的代码

2.如果出现异常,结束try当中的代码,看和catch是否匹配

3.如果匹配到异常类型,执行catch中的代码

4.如果没有匹配到异常类型,向上传递到上层调用者

5.不管有没有匹配,finally的代码都会执行

6,直到传导main也没有处理,由JVM兜底,程序异常终止

4. 自定义异常类

自定义异常类,然后继承自 Exception 或者 RunTimeException
实现一个带有 String 类型参数的构造方法,参数含义:出现异常的原因
public class Test2 {
    public String username = "admain";
    public String password ="123";
    public  void login(String username,String password)throws UserNameException{
            if(!this.username.equals(username)){
                System.out.println("用户名错误");
                throw new UserNameException("用户名错了");

            }
            if(!this.password.equals(password)){
                System.out.println("密码错误");
                throw new PassWordException("密码错了");
            }
    }

    public static void main(String[] args) {
        Test2 test2 = new Test2();
        try {
            test2.login("admin","123");//用户名不对
        }catch (UserNameException e){
            e.printStackTrace();
            System.out.println("用户名异常");
        }catch (PassWordException e){
            e.printStackTrace();
            System.out.println("密码异常");
        }
        finally {

        }
    }
}
用户名错误
用户名异常
Learn.UserNameException: 用户名错了
	at Learn.Test2.login(Test2.java:9)
	at Learn.Test2.main(Test2.java:21)
继承自 Exception 的异常默认是受查异常
继承自 RuntimeException 的异常默认是非受查异常

后记

看到这里,希望能帮到你~

您的点赞 ,收藏 ,关注 是我创作的最大动力!

同时也欢迎在评论区进行交流,共同进步~       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值