Java基础:异常(三)

Java基础:异常(三)


文章目录

  • Java基础:异常(三)
    • [1. Java异常体系](#1. Java异常体系)
      • [1.1 错误的分类](#1.1 错误的分类)
      • [1.2 异常的分类](#1.2 异常的分类)
    • [2. 异常的捕获与处理](#2. 异常的捕获与处理)
      • [2.1 try-catch](#2.1 try-catch)
      • [2.2 finally](#2.2 finally)
    • [3. 异常的抛出](#3. 异常的抛出)
    • [4. 自定义异常](#4. 自定义异常)

1. Java异常体系

Java的异常体系是Java中用于处理运行时错误和其他异常情况的重要机制。它基于一个层次结构,其中Throwable是所有错误和异常的基类。在Java中,主要有两种类型的可抛出对象:ErrorException。Java的异常体系,可以保证程序的健壮性。

1.1 错误的分类

Java中的程序错误分为三类:

  • 编译错误(Compilation Error):编译错误是在程序源代码被编译器处理(即编译)成可执行文件时发生的错误,这些错误通常是由于违反了编程语言的语法规则或编译器无法理解的代码结构造成的。
  • 运行错误(Runtime Error):运行错误是程序在运行时 (即执行时)发生的错误,这些错误通常是由于程序试图执行无效的操作或访问不存在的资源造成的。在Java中,运行错误通常表现为异常(Exception)。异常是一种特殊的对象,用于表示程序运行时的错误情况。
  • 逻辑错误(Logical Error): 逻辑错误是程序在逻辑上不正确或不符合预期的错误,这些错误通常是由于程序员的编程逻辑错误或对问题的不正确理解造成的。逻辑错误不会导致程序崩溃或产生异常,但会导致程序产生不正确的结果或行为。

1.2 异常的分类

Java中的异常分为两类:

  • 检查型异常(Checked Exception):检查型异常在编译时会被检查 ,如果方法可能抛出检查型异常,但该方法没有使用throws关键字声明该异常,或者没有捕获该异常,那么编译器会报错。
检查型异常 说明
IOException 输入输出流异常
SQLException SQL异常
FileNotFoundException 文件找不到异常
ClassNotFoundException 类找不到异常
InterruptedException 线程中断异常
  • 非检查型异常(Unchecked Exception):未检查型异常是指RuntimeException(运行时异常)类及其子类异常,在编译时不会被检查,它们通常是由程序逻辑错误引起的。
运行时异常 说明
RuntimeException 运行时异常父类
ArithmeticException 算术异常,如除零操作
ArrayIndexOutOfBoundsException 数组下标越界异常
NullPointerException 访问null对象引用
NumberFormatException 数字格式异常
java.lang.ClassCastException 类型转换异常

2. 异常的捕获与处理

2.1 try-catch

在一个try块中,可能会产生多个异常,在后面可以接多个catch,去捕捉不同的异常。如果try块中,出现异常,直接进入对应的catch块中,try块中出现异常后的代码不会继续执行。语法格式如下:

java 复制代码
try {  
    // 尝试执行可能会抛出异常的代码  
    // ...  
} catch (ExceptionType1 e) {  
    // 处理ExceptionType1类型的异常  
    // ...  
} catch (ExceptionType2 e) {  
    // 处理ExceptionType2类型的异常  
    // ...  
} 
// 可以有多个catch块来处理不同类型的异常

从JDK7版本之后,可以在一个catch块中,捕捉多个异常。代码示例如下:

java 复制代码
package com.coder.exception;
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入两个数:");
        int x = scanner.nextInt();
        int y = scanner.nextInt();
        int m[] = new int[10];
        try {
            int z = x / y; // y=0
            System.out.println(z);
            m[10] = 10; // 数组下标越界
            System.out.println(m[10]);
        } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) { // >=JDK7版本
            // 获取错误消息
            System.out.println("出现错误:" + e.toString());
        }
    }
}

🆚🆚运行结果:

java 复制代码
请输入两个数:
10 2
5
出现错误:java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10

请输入两个数:
10 0
出现错误:java.lang.ArithmeticException: / by zero

如果trycatch操作出现嵌套情况,内部的catch如果不能处理内部try代码块的异常,则由外部的catch块进行捕捉。代码示例如下:

java 复制代码
public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入两个数:");
        int x = scanner.nextInt();
        int y = scanner.nextInt();
        int m[] = new int[10];
        try {
            int z = x / y; // y=0
            System.out.println(z);
            try {
                m[10] = 20; // 数组下标越界
                System.out.println(m[10]);
                //String str = null;
                //System.out.println(str.toLowerCase());
            } catch (NullPointerException e) { // 非检查型异常 空指针异常
                System.out.println("数组下标越界");
            }
        } catch (ArithmeticException e) {
            // 打印异常堆栈轨迹
            e.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("外面的catch块处理数组下标越界");
        }
    }
}

🆚🆚运行结果:

java 复制代码
请输入两个数:
10 2
5
外面的catch块处理数组下标越界

请输入两个数:
10 0
java.lang.ArithmeticException: / by zero
	at com.coder.exception.Test.main(Test.java:18)

📌:异常消息的处理包括:

  1. e.getMessage(),获取异常信息;
  2. e.toString(),获取异常类和信息;
  3. e.printStackTrace(),打印异常堆栈轨迹。

2.2 finally

以下是finally的执行流程:

其语法格式如下:

java 复制代码
try {
    // 尝试执行可能会抛出异常的代码
} catch (具体的异常类 e) {
} finally {
    //释放资源
}
  • 使用finally完成资源释放。例如:关闭打开的连接,删除临时文件,关闭打开文件。
  • finally不管是否出现异常,都会被执行到。如果trycatch块中,有return语句,finallyreturn
    码之前执行。
  • 如果trycatch代码块中,执行了System.exit(0)退出虚拟机操作,finally代码块中的语句不再执行。

代码示例如下:

java 复制代码
public class Test2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入两个数:");
        int x = scanner.nextInt();
        int y = scanner.nextInt();
        int m = test(x, y);
        System.out.println(m);
    }

    public static int test(int x, int y) {
        System.out.println("进入test方法");
        int z = 0;
        try {
            z = x / y; // y=0
            System.out.println("除法执行完成");
            System.exit(0);  // 退出虚拟机操作
            return z;
        } catch (ArithmeticException e) {
            return 0;
        } finally {
            System.out.println("关闭连接");
            return -1;
        }
    }
}

🆚🆚运行结果:

java 复制代码
请输入两个数:
10 2
进入test方法
除法执行完成

10 0
进入test方法
关闭连接
-1

📌trycatchfinally不能单独使用:

  1. trycatch使用;
  2. trycatchfinally使用;
  3. tryfinally使用。

3. 异常的抛出

  • throws用法:用于声明一个方法可能会抛出的异常列表,但它并不处理这些异常。谁来调用这个方法,谁处理这些异常。throws后面可以接多个异常类型,中间使用逗号分隔。
  • throw用法:使用throw抛出明确的异常处理,语法格式:throw new ExceptionType(parameters);throw在方法体内的语句,如果抛出的是运行时异常,可以不需要做任何处理。如果抛出的是检查型异常,不能单独使用,必须要配合try-catch或者throws使用。

代码示例如下:

java 复制代码
public class Test4 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入姓名和年龄:");
        String name = scanner.next();
        int age = scanner.nextInt();
        System.out.println("姓名:" + name + "," + "年龄:" + age);
        Person person = new Person(name, age);
        // 2. 使用try-catch块:处理检查型异常时,在调用方法的代码周围使用try-catch块来捕获并处理异常。
        try {
            checkPersonInfo(person);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 1. 在方法签名中使用throws关键字:如果你不想在当前方法中处理异常,你可以使用throws关键字将异常声明给方法的调用者。
    public static void checkPersonInfo(Person person) throws FileNotFoundException {
        if (person.getAge() < 18) {
            throw new NullPointerException("年龄必须在18岁以上"); // 使用throw抛出运行型异常
        }
        if (person.getName().length() < 2) {
            throw new FileNotFoundException("姓名必须是2位以上"); // 使用throw抛出检查型异常,必须要配合try-catch或者throws使用
        }
    }
}

🆚🆚运行结果:

java 复制代码
请输入姓名和年龄:
张三 10
姓名:张三,年龄:10
Exception in thread "main" java.lang.NullPointerException: 年龄必须在18岁以上
	at com.coder.exception.Test4.checkPerName(Test4.java:30)
	at com.coder.exception.Test4.main(Test4.java:21)

请输入姓名和年龄:
张 18
姓名:张,年龄:18
java.io.FileNotFoundException: 姓名必须是2位以上
	at com.coder.exception.Test4.checkPerName(Test4.java:33)
	at com.coder.exception.Test4.main(Test4.java:21)

📌

  1. 运行时异常通常表示编程错误或不可恢复的错误情况,如数组越界、空指针引用等。因此,在编写代码时应该尽量避免抛出运行时异常,除非确实出现了无法恢复的错误。
  2. 与检查型异常不同,运行时异常在方法签名中不需要使用throws关键字来声明。这是因为运行时异常在编译时期不会被检查,所以编译器不会强制要求你处理这些异常。
  3. 虽然运行时异常在编译时期不需要被显式处理,但在实际编程中,最好还是捕获并处理这些异常,以确保程序的健壮性和可维护性。

4. 自定义异常

自定义异常是指在Java程序中根据特定业务需求创建的异常类,这些类继承自Exception类或其子类(如RuntimeException),以提供更详细的错误信息和更准确地表达特定的业务含义。代码示例如下:

java 复制代码
public class AgeException extends Exception{
    public AgeException(){
        super("年龄不符合要求");
    }
    public AgeException(String message){
        super(message);
    }
}

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

以上内容是关于Java异常的基础知识,希望对初学者或再次学习者有所帮助,基础打扎实,不怕风吹雨打!如果以上内容有错误或者内容不全,望大家提出!我也会继续写好每一篇博文!

👍👍👍

待续未完

🙊🙊🙊

欢迎观看和提问!!!

👏👏👏

相关推荐
王俊山IT11 分钟前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。13 分钟前
c++多线程
java·开发语言
小政爱学习!15 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
daqinzl21 分钟前
java获取机器ip、mac
java·mac·ip
k093330 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
激流丶37 分钟前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
神奇夜光杯38 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue40 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧42 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
测试界的酸菜鱼1 小时前
Python 大数据展示屏实例
大数据·开发语言·python