Java异常

Exception与Error

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

  • Error(错误):Java虚拟机无法解决的严重问题。是系统中的错误,大多数与程序员的操作无关,程序员是不能改变和处理的,不需要关心这类错误。例如:StackOverflowError(栈溢出)和OOM(内存溢出)
  • Exception(异常): 在程序运行期间,发生的不被期望的事件,阻止了程序按照程序员的预期正常执行(开发过程中的语法错误和逻辑错误不是异常)。可以使用针对性的代码进行处理。例如:空指针访问、试图读取不存在的文件、网络连接中断、数组角标越界、非法参数

异常分类

  • 检查型异常:最具代表性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如用户要打开一个不存在的文件时引发的异常,这些异常在编译时不能被简单地忽略
  • 运行时异常:是可能被程序员避免的异常,与检查性异常相反,运行时异常可以在编译时忽略

异常示例

  • java.lang.StackOverflowError 栈堆异常

    Java 复制代码
    public class Demo01 {
        public static void main(String[] args) {
            new Demo01().a();  //创建一个Demo01类的实例,并调用其a方法。
        }
    
        public void a(){
            b();
        }
        public void b(){
            a();
        }
    }
    //在方法a中,调用了方法b;在方法b中,又调回了方法a。如此反复,陷入了一个无限循环。
  • java.lang.ArithmeticException 算数运算异常

    Java 复制代码
    public class Demo02 {
        public static void main(String[] args) {
            System.out.println(11/0);
        }
    }

异常体系结构

Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类,Throwable又派生出Error类和Exception类。

异常处理机制

捕获异常

当程序中抛出一个异常后,如果该异常没有被捕获和处理,程序将终止。 可以使用try-catch语句来捕获异常。try块用于包含可能抛出异常的代码,而catch块用于捕获并处理异常。

语法格式

java 复制代码
try {
    // 可能会抛出异常的代码
} catch (ExceptionType1 e) {
    // 处理ExceptionType1异常的代码
} catch (ExceptionType2 e) {
    // 处理ExceptionType2异常的代码
}finally {
    // 可选的finally块,无论是否发生了异常。这个块里的代码总是会被执行,除非程序中止
    //用于在发生异常或未发生异常时执行清理工作 
}

在上述代码中:

  • catch块用于捕获并处理在try块中抛出的异常。可以有一个或多个catch块,每个块处理一种特定类型的异常。在每个catch块中,可以编写处理特定异常的代码。例如,可能想要记录异常信息,或者尝试以某种方式恢复程序的执行
  • ExceptionType1ExceptionType2是Java中预定义的异常类或自定义的异常类。它们表示特定类型的异常
  • ecatch块中声明的变量,表示捕获的异常对象。可以使用这个变量来访问有关异常的信息,如异常的消息或堆栈跟踪

getMessage() 方法

getMessage() 方法定义在 Throwable 类中,因此它可以在任何从 Throwable 继承的类(如异常类)中直接使用,而不需要单独定义。当捕获到异常时,可以直接调用异常对象的 getMessage() 方法,以获取异常的描述信息

应用:当异常被捕获时,可以通过catch块中的参数e(或者自定义的异常变量名)来访问异常对象。e.getMessage()方法将返回一个字符串,其中包含有关异常的描述或详细信息。

示例

java 复制代码
try {
    int[] arr = new int[5];
    arr[10] = 100; // 这将抛出一个ArrayIndexOutOfBoundsException异常
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("数组越界异常: " + e.getMessage());
    //这个异常被第一个catch块捕获,并输出一条包含异常消息的错误信息
} catch (Exception e) {
    System.out.println("其他异常: " + e.getMessage());
    //如果try块中的代码抛出其他类型的异常,它将被第二个catch块捕获,并输出一条包含异常消息的错误信息
}

快捷键

  1. 按下Ctrl+Alt+T快捷键,打开代码生成菜单
  2. 在菜单中选择"Surround With"选项
  3. 在弹出的列表中选择"Try/Catch"选项
  4. 按下Enter键,IDEA会自动在光标所在行的下一行插入一个try-catch代码块

抛出异常

除了捕获异常,还可以在程序中主动抛出异常 在Java中,可以使用throw关键字来显式地抛出一个异常。在try-catch语句中,一旦使用throw抛出一个异常,程序控制将立即转到最近的能够处理该异常的catch

语法格式

Java 复制代码
throw new 异常类型(参数);   //参数 是可选的,用于初始化异常对象

当使用throw语句抛出异常后,程序将立即停止执行后面的代码,并跳转到能够处理该异常的catch块。如果没有找到合适的catch块来处理异常,程序将终止

示例

java 复制代码
public class Example {
    public static void main(String[] args) {
        try {
            int[] arr = new int[5];
            throw new ArrayIndexOutOfBoundsException("数组越界异常");
            arr[10] = 100;   // 这行代码不会被执行,因为throw语句已经抛出了异常
        } catch (ArrayIndexOutOfBoundsException e) {   //程序控制立即转到第一个catch块
            System.out.println("捕获到数组越界异常: " + e.getMessage());  
            //并输出一条包含异常消息的错误信息
        } catch (Exception e) {
            System.out.println("捕获到其他异常: " + e.getMessage());
        }
    }
}

自定义异常

  1. 创建自定义异常类,继承自Exception或Exception子类
  2. 在方法中通过throw关键字抛出异常对象
  3. 如果在抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常
  4. 在出现异常方法的调用者中捕获并处理异常
Java 复制代码
public class Demo02 {
    public static void main(String[] args) {
        try {
            test(11);
        } catch (MyException e) {
            System.out.println("MyException->" + e); // 打印 MyException->MyException{detail=11}
//这里使用了异常对象e的toString()方法,该方法覆盖了从Exception类继承的方法,返回一个描述异常的字符串
        }
    }
    public static void test(int a) throws MyException {
    //定义了一个名为test的公共静态方法,它接受一个整数参数并可能抛出一个MyException异常
        if (a>10){
            throw new MyException(a);
//抛出一个新的MyException异常,并传递参数a作为详细信息。这将导致程序跳回到调用此方法的主方法中,并执行相应的catch块来处理这个异常
        }
    }
}

class MyException extends Exception{  //自定义异常类MyException的定义
    private int detail;

    public MyException(int detail) {
        this.detail = detail;
    }

    @Override
    public String toString() {  // 重写Exception类的toString方法,返回异常的字符串表示形式
        return "MyException{" + "detail=" + detail + '}';   // 返回包含detail值的字符串
    }
}
相关推荐
尼克_张2 分钟前
tomcat配合geoserver安装及使用
java·tomcat
wywcool15 分钟前
JVM学习之路(5)垃圾回收
java·jvm·后端·学习
-seventy-34 分钟前
Java Web 工程全貌
java
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ39 分钟前
idea 删除本地分支后,弹窗 delete tracked brank
java·ide·intellij-idea
言慢行善40 分钟前
idea出现的问题
java·ide·intellij-idea
杨荧1 小时前
【JAVA毕业设计】基于Vue和SpringBoot的宠物咖啡馆平台
java·开发语言·jvm·vue.js·spring boot·spring cloud·开源
Ling_suu1 小时前
Spring——单元测试
java·spring·单元测试
ModelBulider1 小时前
十三、注解配置SpringMVC
java·开发语言·数据库·sql·mysql
苹果酱05672 小时前
C语言 char 字符串 - C语言零基础入门教程
java·开发语言·spring boot·mysql·中间件
csucoderlee2 小时前
eclipse mat leak suspects report和 component report的区别
java·ide·eclipse