• 【JAVA知识梳理】异常机制


    活动地址:CSDN21天学习挑战赛

    本文已收录于专栏
    ⭐️ 《java 知识梳理》⭐️

    异常机制

    在 java 语言中,将程序执行中发生的不正常情况称为"异常"。

    (开发过程中的语法错误和逻辑错误不是异常)

    执行过程中所发生的异常事件可分为两大类

    1)Error(错误):java 虚拟机无法严重问题。

    如:JVM系统内部错误、资源耗尽等严重情况。

    比如:StackOverflowError【栈溢出】和 OOM(out of memory),error 是严重错误,程序会崩溃。

    2)Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。

    Exception 分为两大类:运行时异常和编译时异常。

    比如:空指针访问,试图读取不存在的文件,网络连接中断等等。

    异常体系图

    在这里插入图片描述

    异常处理机制

    抓抛模型:

    过程一:‘抛’,程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个并将对象抛出。

    一旦抛出对以后,其后的代码就不再执行。

    过程二:‘抓’,可以理解为异常的处理方式:

    ①try-catch - finally ② throws

    try-catch 处理机制

    如果程序员,认为一段代码可能出现异常/问题,可以使用 try-catch 异常处理机制来解决 。

    从而保证程序的健壮性。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eQhu9YZy-1659795028506)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220523130655608.png)]

    将该代码块->选中->快捷键 ctrl + alt + t -> 选中 try-catch

    try {
    	//可能出现的异常
    }catch(异常类型1 变量名 1){
    	//处理异常的方式
    }catch(异常类型2 变量名 2){
    	//处理异常的方式
    }finally{
        // 1 .不管 try 代码块 是否有异常发生,始终要执行 finally
        // 2 .所以通常被释放资源的代码放在 finally
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    如果进行异常处理,那么即使出现了异常,程序可以继续执行。

    try{
    	int res = num1 = num2;
    }catch(Exception e){
        e.prinStackTrace();
        //输出异常信息
        System.out.println("异常出现的原因:"+e.getMesssage());
        //by zero
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    throw机制图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UNp3yTRG-1659795028508)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220523130951068.png)]

    运行异常

    对于运行时异常,可以不做处理,以为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。

    NullPointerException

    空指针异常:当应用程序试图在需要对象的地方使用 null 时,抛出该异常。

    实例代码:

    public class NullPointerException_ { 
    
        public static void main(String[] args) { 
    
        String name = null; 
    
        System.out.println(name.length()); 
        } 
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ArithmenticException

    数学算数异常:当出现异常运算条件时,抛出此异常。

    例如,一个整数“除以零”时,抛出此类的一个实例

    ArrayIndexOutOfBoundException

    数组标越界异常:用非法索引访问数组抛出的异常。

    如果索引为负或大于等于数组大小,则该索引为非法索引。

    ClassCastException

    类型转换异常:当试图将对象强制转移为不是实例的子类时,抛出该异常。

    实例代码:

    public class ClassCastException_ { 
    
        public static void main(String[] args) { 
    
        A b = new B(); //向上转型 
    
        B b2 = (B)b;//向下转型,这里是 OK 
    
        C c2 = (C)b;//这里抛出 ClassCastException 
    
        } 
    
        }
    
        class A {} 
    
        class B extends A {} 
    
        class C extends A {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    NumberFromatException

    数字格式不正确异常:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常 => 使用异常我们

    可以确保输入是满足条件数字.

    实例代码:

    public class NumberFormatException_ { 
    
        public static void main(String[] args) { 
    
        String name = "韩顺平教育"; 
    
        //将 String 转成 int 
    
        int num = Integer.parseInt(name);//抛出 NumberFormatException 
    
        System.out.println(num);//1234 
    
        } 
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    编译异常

    编译异常是指在编译期间,就必选处理的异常,否则代码不能通过编译。

    SQLException 操作数据库时,查询表可能发生异常

    IOException 操作文件时,发生的异常

    FileNotFoundException 加载类,而该类不存在时,异常

    EOFException 操作文件,到文件末尾,发生异常

    try-catch 异常处理

    快捷键:ctrl + atl + t

    1.如果异常发生了,则异常发生后面的代码不会执行,直接进入到 catch 块

    2.如果异常没有发生,则顺序执行 try 的代码块,不会进入到 catch

    3.如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用如下代码- finally

    public class TryCatchDetail { 
    public static void main(String[] args) { 
    try { 
    String str = "韩顺平"; 
    int a = Integer.parseInt(str); 
    System.out.println("数字:" + a); 
    } catch (NumberFormatException e) { 
    System.out.println("异常信息=" + e.getMessage()); 
    } finally { 
    System.out.println("finally 代码块被执行..."); 
    }
    System.out.println("程序继续..."); 
    } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.如果 try 代码块有可能有多个异常

    2.可以使用多个 catch 分别捕获不同的异常,相应处理

    3.要求子类异常写在前面,父类异常写在后面

    public class TryCatchDetail02 { 
    public static void main(String[] args) { 
        try { 
            Person person = new Person(); 
            //person = null; 
            System.out.println(person.getName());//NullPointerException 
            int n1 = 10; 
            int n2 = 0; 
            int res = n1 / n2;//ArithmeticException 
            } catch (NullPointerException e) { 
            System.out.println("空指针异常=" + e.getMessage()); 
            } catch (ArithmeticException e) { 
            System.out.println("算术异常=" + e.getMessage()); 
            } catch (Exception e) { 
            System.out.println(e.getMessage()); 
            } finally { 
            } 
        } 
    }
    class Person { 
    private String name = "jack"; 
    public String getName() { 
    return name; 
    } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    throw 异常处理

    1.对于编译异常,程序中必选处理,比如 try - throw

    2.对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理

    3.子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型。

    4.在 throw 过程中,如果有 方法 try - catch ,就相当于处理异常,就可以不必 throws

    class Father { //父类 
        public void method() throws RuntimeException { 
        } 
    }
    class Son extends Father {//子类 
    //3. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法, 
    // 所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型 
    //4. 在 throws 过程中,如果有方法 try-catch , 就相当于处理异常,就可以不必 throws 
    @Override 
    public void method() throws ArithmeticException { 
        // ArithmeticException是RuntimeException子类
    } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    当调用的是 抛出编译异常的方法时

    要么 try-catch-finally ,或者继续 throws 这个编译异常

    public static void f1() throws FileNotFoundException { //抛出异常
    
    //这里大家思考问题 调用 f3() 报错 
        
    //1. 因为 f3() 方法抛出的是一个编译异常 
    
    //2. 即这时,就要 f1() 必须处理这个编译异常 
    
    //3. 在 f1() 中,要么 try-catch-finally ,或者继续 throws 这个编译异常 
    
    f3(); // 编译异常
    
    }
    
    public static void f3() throws FileNotFoundException { // 抛出的是编译异常
    
    FileInputStream fis = new FileInputStream("d://aa.txt"); 
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    当调用的是 抛出的是运行异常时

    因为有 throw 默认处理机制 ,所以可以正常调用

    public static void f4() { 
    
    //1. 在 f4()中调用方法 f5() 是 OK 
    
    //2. 原因是 f5() 抛出的是运行异常 
    
    //3. 而 java 中,并不要求程序员显示处理,因为有默认处理机制 
    
    f5(); 
    
    }
    
    public static void f5() throws ArithmeticException { //抛出的是运行异常 
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    自定义异常

    定义类:自定义异常类继承 Exception 或 RuntimeException

    如果继承 Exception,属于编译异常。

    如果继承 RuntimeException,属于运行异常

    1.一般情况下,我们自定义异常是继承 RuntimeException

    2.即把自定义异常做成 运行时异常,好处时,我们可以使用默认的处理机制

    3.即比较方便

    public class CustomException { 
    public static void main(String[] args) /*throws AgeException*/ { 
        int age = 180; 
        //要求范围在 18 – 120 之间,否则抛出一个自定义异常 
        if(!(age >= 18 && age <= 120)) { 
        //这里我们可以通过构造器,设置信息 
        throw new AgeException("年龄需要在 18~120 之间"); 
    	}
      System.out.println("你的年龄范围正确."); 
     } 
    }
    class AgeException extends RuntimeException { 
        public AgeException(String message) {//构造器 
        super(message); 
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    抛出异常和return同一个级别的,只要执行方法就结束,所以 finally 必须先执行,否则就执行不到finally

    完结散花

    ok以上就是对 异常机制 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。

    参考文献

    韩顺平JAVA基础笔记

  • 相关阅读:
    ROS小车1_ssh远程登陆小车
    hudi系列-旧文件清理(clean)
    以太坊核心开发者建议合并的暂定日期
    Mysql 我随手造200W条数据,给你们讲讲分页优化。
    Vue动态组件 Components
    lombok的@Data注解
    【PCL自学:Segmentation4】基于Min-Cut点云分割
    【向大佬学习uvm】UVM_Agent中一般包含哪些内容
    基于Python开发的AI智能联系人管理程序(源码+可执行程序+程序配置说明书+程序使用说明书)
    linux的dirty page回写磁盘过程中是否允许并发写入更新page?
  • 原文地址:https://blog.csdn.net/m0_66139206/article/details/126202245