• JavaSE:异常处理


    前言

    这段时间刚好开始复习Java,就顺便把笔记整理成博客,巩固一下知识。

    一、异常概述与异常体系结构

    1、概述

    在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的。比如: 客户输入数据的格式读取文件是否存在网络是否始终保持通畅等等。

    异常:在Java语言中, 将程序执行中发生的不正常情况称为“异常” 。
    (开发过程中的语法错误和逻辑错误不是异常)

    2、分类

    Java程序在执行过程中所发生的异常事件可分为两类:

    • Error: Java虚拟机无法解决的严重问题。 如: JVM系统内部错误、 资源耗尽等严重情况。比如:StackOverflowErrorOOM。 一般不编写针对性的代码进行处理。
    • Exception: 其它因编程错误或偶然的外在因素导致的一般性问题, 可以使用针对性的代码进行处理。 例如:
      1、空指针访问
      2、试图读取不存在的文件
      3、网络连接中断
      4、数组角标越界

    对于Error来说,错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。因此我们编写程序时不需要关心这类异常。

    所以我们主要讨论Exception。

    3、Exception异常

    Exception是程序本身可以处理的异常。异常处理通常指针对这种类型异常的处理。Exception类的异常包括 checked exception(受检异常) 和 unchecked exception(非受检异常)。

    (1)checked exception

    编译时异常(checked):
    Java编译器会检查这些异常,当程序中可能出现这类异常时,要求必须进行异常处理,否则编译不会通过。

    (2)unchecked exception

    运行时异常(unchecked):
    Java编译器不会检查这些异常,在程序中可以选择捕获处理,也可以不处理,照样正常编译通过。

    二、异常处理机制

    1、捕获异常:try-catch-finally

    (1)概念

    Java提供 try 和 catch 块来处理异常。try块用于包含可能出错的代码,catch块用于处理try块中发生的异常。可以根据需要在程序中有多个try - catch 块。

    (2)语法

    try {
    	// 可能出现异常的代码块
    } catch (异常类型1 变量名1) {
    	// 对异常的处理1
    } catch (异常类型2 变量名2) {
    	// 对异常的处理2
    } catch (异常类型3 变量名3) {
    	// 对异常的处理3
    }
    ...
    finally {
    	// 无论成功与否都会执行的代码块
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    (3)注意

    1. 如果发生异常,则异常后面的代码不会执行,生成一个对应异常类的对象,进入 catch 代码块进行匹配;
    2. 如果没有发生异常,则顺序执行 try 代码块,不会进入到 catch 代码块;
    3. 如果发生异常,只会匹配一个 catch,处理完成后,会进入 finally 代码块(如果没有,则跳出当前 try-catch 结构);
    4. finally 代码块的有无是根据需要来决定的;
    5. 有多个 catch 语句时,,要求父类异常在后,子类异常在前;
    6. 常用的异常对象获取方式:
      ①getMessage():获取异常信息,返回字符串
      ②printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

    (4)样例

    public class Test {
        public static void main(String[] args) {
            try {
                int a = 10;
                int b = 0;
                System.out.println(a / b);
            } catch (ArithmeticException e) {
                System.out.println("出现运算异常了");
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
            
            System.out.println("111");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    运行结果:
    在这里插入图片描述

    (5)finally

    举例:

    public class Test1 {
        public static void main(String[] args) {
            int num = func();
            System.out.println(num);
        }
    
        public static int func() {
            try {
                int[] arr = new int[10];
                System.out.println(arr[10]);
                return 1;
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
                return 2;
            } finally {
                System.out.println("等一等,还有finally");
                return 3;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    运行结果:
    在这里插入图片描述
    通过上述例子,我们可以发现:

    不论在 try 代码块中是否发生了异常事件, catch 语句是否执行, catch 语句是否有异常, catch 语句中是否有 return,finally 块中的语句都会被执行。

    像数据库连接,输入输出流,网络编程socket等资源,JVM是不能自动回收的,我们需要手动的进行资源的释放。此时的资源的释放,就需要声明在finally中。

    2、抛出异常:throws 和 throw

    (1)throws

    ①概念

    throws关键字常用于方法上,表示方法可能抛出异常,当方法抛出多个异常时,可用逗号分隔异常类型名。

    ②语法

    返回值类型 方法名(参数)throws 异常类型名{
    }
    
    • 1
    • 2

    ③样例

    public class Test2 {
        public static void main(String[] args) throws ArithmeticException {
            int a = 10;
            int b = 0;
            System.out.println(a / b);
            System.out.println("111");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    运行结果:
    在这里插入图片描述

    ④注意

    • 一旦方法体执行时出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足 throws 后异常类型时,就会被抛出,异常代码后续的代码,就不再执行;
    • 子类重写父类方法时,子类重写的方法,所抛出的异常类型不大于父类抛出的异常类型;

    (2)try-catch 和 throws

    1. 对于编译时异常,程序中必须处理,比如 try-catch 和 throws;
    2. 对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理。
    3. 执行的方法a中,先后又调用了另外几个递进关系的方法,则这几个方法使用 throws,然后方法a使用 try-catch。

    (3)throw

    ①概念

    throw关键字虽然可以用于抛出Exception类中的子类异常,但更重要的用途是抛出自定义异常。

    ②语法

    throw new 异常类型名(异常信息)
    
    • 1

    ③样例

    public class Test3 {
        public static void main(String[] args) {
            try{
                Student stu =new Student();
                stu.fun(17);
                System.out.println(stu);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
    }
    
    class Student{
        private int age;
    
        public void fun(int age){
            if(age>18&&age<22){
                this.age=age;
            }else{
                throw new AgeException("范围:18 < age < 22");
            }
            System.out.println("输入成功");
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "age=" + age +
                    '}';
        }
    }
    
    class AgeException extends RuntimeException{
        public AgeException(String s){
            super(s);
        }
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    运行结果:
    在这里插入图片描述

    三、用户自定义异常类

    (1)概念

    当程序中出现了某些“错误”,但是该错误信息并没有在 Throwable 子类中描述处理,这个时候可以自己设计异常类,用于描述该错误信息。

    (2)语法

    • 继承现有的异常结构;
    • 提供全局变量;
    • 提供重载的构造器。
    public class MyException extends RuntimeException{
    	static final long serialVersionUID = -7034897190745766939L;
        
        public MyException(){
            
        }
    
    	public MyException(String message) {
    		super(message);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    总结

    终于把异常处理的博客补完了,距离成功又进了一步,加油!!!

  • 相关阅读:
    分享一套GitHub上stars 10000+的Java面试题(含解析)
    本来打算做功能测试的,但是发现playwright太好玩了,玩了一天,功能测试进度为空
    基于机器学习的节日大促营销模型
    《JAVA设计模式系列》模板模式
    网络路径监控分析
    【一起学Java-第八篇】Java语言类的特性详解
    2023/9/9总结
    迁移kubelet、docker和containerd工作目录
    Pulsar Manager和dashboard部署和启用认证
    第十二章 Spring Cloud Config 统一配置中心详解-客户端动态刷新
  • 原文地址:https://blog.csdn.net/WZRbeliever/article/details/125286672