JavaSE系列Java异常处理机制

Posted 未见花闻

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE系列Java异常处理机制相关的知识,希望对你有一定的参考价值。

⭐️前面的话⭐️

本篇文章带大家认识Java基础知识——异常,在理想的情况下,用户输入的数据格式永远是正确的,一个程序也许可能永远没有bug,但是在实际情况当中,这种理想的情况非常少,用户输入数据格式出现错误是非常常见的,需要一种机制解决类似的问题,而在Java中引入了异常的概念,本篇博客将围绕什么是异常,异常怎么解决两个维度对异常做一个详细地分析。

📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2021年12月8日🌴
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《Java核心技术》,📚《Java编程思想》,📚《Effective Java》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🙏作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!




1.初见Java异常

1.1熟悉的面孔

在Java的学习过程中,一定遇到过除数为0,数组越界,对空引用操作等,这些情况可以通过编译,但是在运行的时候编译器会报出异常,这些异常就是Java异常机制中的一部分。

System.out.println(10 / 0);//除数为0

int[] arr = new int[10];
System.out.println(arr[11]);

String str = null;
System.out.println(str.length());


A r i t h m e t i c E x c e p t i o n , A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n , N u l l P o i n t e r E x c e p t i o n ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException ArithmeticExceptionArrayIndexOutOfBoundsExceptionNullPointerException都是初学Java时常遇到的一部分异常,但是Java异常机制包括的不仅仅只有异常,还有错误也是属于Java异常机制范围内的。

1.2防御式编程

错误在代码中是客观存在的. 因此我们要让程序出现问题的时候及时通知程序猿, 我们有两种主要的方式:
LBYL: Look Before You Leap. 在操作之前就做充分的检查.
EAFP: It’s Easier to Ask Forgiveness than Permission. “事后获取原谅比事前获取许可更容易”. 也就是先操作, 遇到问题再处理.

打个比方,有一天你心血来潮,看到一位非常漂亮的小姐姐,你很想牵她的手,但是你非常的有礼貌,先询问这位小姐姐:我能牵你的手吗?,这位小姐姐毫不犹豫地说:不行!,这一种情形就是LBYL方式;与此同时,另一位比较强悍的兄弟也想牵这位小姐姐的手,于是直接拿起这位小姐姐的手,牵了起来,然后这位小兄弟被扇了一巴掌,这种情形就是EAFP方式。
Java异常核心思想就是EAFP。

1.3异常的优点

使用异常能够更好地处理业务,代码也更有条理,更加清晰明白,不使用异常代码正常的代码与可能异常的代码混在一起,比较混乱。
比如一个模拟实现一个游戏开始的过程:

不使用异常:

public class Test2 
    public static void main(String[] args) 
        boolean ret = false;//账号密码匹配结果
        ret = 密码验证结果();
        if (!ret) 
            //处理游戏登录失败业务
        
        ret = 加载游戏结果();
        if (!ret) 
            //处理加载游戏失败业务
        
        ret = 联机匹配结果();
        if (!ret) 
            //处理联机匹配失败业务
        
        ret = 氪金是否成功结果();
        if (!ret) 
            //处理氪金失败业务
        
    

使用异常:

public class Test2 
    public static void main(String[] args) 
        try 
            密码验证();
            加载游戏();
            联机匹配();
            氪金();
        catch (密码验证异常) 
            //处理密码错误异常
        catch (加载游戏异常) 
            //处理加载游戏异常
        catch (联机匹配异常) 
            //处理联机匹配异常
        catch (氪金异常) 
            //处理氪金异常
        
    

2.异常处理

2.1捕获异常

想要捕获一个异常,前提需要知道可能会发生什么类型的异常,最常见的异常就是前面所举例的 A r i t h m e t i c E x c e p t i o n , A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n , N u l l P o i n t e r E x c e p t i o n ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException ArithmeticExceptionArrayIndexOutOfBoundsExceptionNullPointerException分别为除数为0异常,数组越界异常,空指针异常。
当然,Java异常体系中的异常种类非常多,Exception类下的直接子类就有:

RuntimeException类是目前我们接触最多的,前面列举的几个常见的异常都是该类的子类。

2.1.1捕获一个异常

我们在进行除法计算时,可能会出现除数为0,访问数组对象时,可能出现数组越界,使用一个对象时,可能会出现空指针异常,知道一段代码可能出现某种或某些异常,我们可以对异常进行捕获,语法规则为:

try 
        //可能出现异常的代码段
catch (异常类 异常变量名) 
       //处理该异常

try 代码块中放的是可能出现异常的代码。
catch代码块中放的是出现异常后的处理行为。

public class Test3 
    public static void main(String[] args) 
        int a = 0;
        try 
            System.out.println(8 / a);
        catch (ArithmeticException e) 
            System.out.println("捕捉到了除数为0异常!");
        
        int[] arr = new int[10];
        try 
            System.out.println(arr[20]);
        catch (ArrayIndexOutOfBoundsException e) 
            System.out.println("捕捉到了一个数组越界异常!");
        
        String str = null;
        try 
            System.out.println(str.equals("aaa"));
        catch (NullPointerException e) 
            System.out.println("捕捉到了一个空指针异常!");
        
    


可以调用异常类中的 p r i n t S t a c k T r a c e ( ) 方 法 printStackTrace()方法 printStackTrace()打印异常错误信息:

public class Test3 
    public static void main(String[] args) 
        int a = 0;
        try 
            System.out.println(8 / a);
        catch (ArithmeticException e) 
            e.printStackTrace();
            System.out.println("捕捉到了除数为0异常!");
        
        int[] arr = new int[10];
        try 
            System.out.println(arr[20]);
        catch (ArrayIndexOutOfBoundsException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个数组越界异常!");
        
        String str = null;
        try 
            System.out.println(str.equals("aaa"));
        catch (NullPointerException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个空指针异常!");
        
    


如果异常没有被主动捕捉(使用try…catch语句捕捉),这个异常会交给JVM处理,一旦交给JVM处理,发生异常,将非正常终止程序,后续代码不会执行。

public class Test6 
    public static void main(String[] args) 
        int[] arr = new int[10];
        System.out.println(arr[20]);//发生数组越界异常,该异常没有被捕获,将交给JVM处理
        System.out.println("我是异常代码的后续代码,我被执行了!");
    


代码非正常退出,异常处后的代码不会被执行!

主动捕获异常,异常处后面的代码会执行,并且程序正常退出:

public class Test5 
    public static void main(String[] args) 
        int[] arr = new int[10];
        try 
            System.out.println(arr[20]);
        catch (ArrayIndexOutOfBoundsException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个数组越界异常!");
        
        System.out.println("我是异常代码的后续代码,我被执行了!");
    

2.1.2捕获多种异常

Java异常机制支持多种异常的捕获,最常用的方法,就是使用多个catch语句,捕捉多个异常的具体类型。
一个try…catch语句,catch语句可以存在多个:

public class Test4 
    public static void main(String[] args) 
        try 
            //可能出现异常的代码段
        catch (异常类 异常变量名) 
            //处理该异常
        catch (...) 
            //处理
        ...
    

而对于try语句中的代码段,当代码段中遇到异常时,发生异常的后面的所有代码段将不再执行,会直接执行对应catch中的语句。
比如,我将三句都有异常的代码写在同一个try语句中,使用多个catch语句捕捉这三种类型的异常,实际上只会捕捉到第一个异常。

public class Test7 
    public static void main(String[] args) 
        int a = 0;
        int[] arr = new int[10];
        String str = null;
        try 
            System.out.println(8 / a);
            System.out.println(arr[20]);
            System.out.println(str.equals("aaa"));
         catch (ArithmeticException e) 
            e.printStackTrace();
            System.out.println("捕捉到了除数为0异常!");
         catch (ArrayIndexOutOfBoundsException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个数组越界异常!");
         catch (NullPointerException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个空指针异常!");
        
    


try语句中第一个异常语句为除数为0而引发的算术异常,所以最终捕捉的异常只有算术异常。
如果第一个语句没有异常,则捕捉的是后面第一个发生异常语句的异常,也就是说一个try语句只能捕获一个异常。

public class Test7 
    public static void main(String[] args) 
        int a = 2;
        int[] arr = new int[10];
        String str = null;
        try 
            System.out.println(8 / a);
            System.out.println(arr[20]);
            System.out.println(str.equals("aaa"));
         catch (ArithmeticException e) 
            e.printStackTrace();
            System.out.println("捕捉到了除数为0异常!");
         catch (ArrayIndexOutOfBoundsException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个数组越界异常!");
         catch (NullPointerException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个空指针异常!");
        
    


除了使用多个catch语句,还可以使用|分隔符在一个catch语句中定义多种类型的异常类:

public class Test8 
    public static void main(String[] args) 
        int[] arr = new int[10];
        String str = null;
        try 
            System.out.println(2/0);
         catch (ArrayIndexOutOfBoundsException | NullPointerException | ArithmeticException e) 
            e.printStackTrace();
            System.out.println("捕捉到了一个除数为0异常或数组越界异常或空指针异常!");
        
    

public class Test8 
    public static void main(String[] args) 
        int[] arr = new int[10];
        String str = null;
        try 
            System.out.println(arr[20]);
            System.out.println(str.equals("aaa"));
         catch (ArrayIndexOutOfBoundsException | NullPointerException | ArithmeticException e) 
            eJava异常处理机制

JavaSE学习总结

JavaSE(基础篇)——异常机制

JavaSE---异常

16 Java中异常的处理

JavaSE--异常机制