首页 > 编程语言 >[Java基础] 异常处理机制

[Java基础] 异常处理机制

时间:2024-10-19 20:48:22浏览次数:3  
标签:Java 处理 抛出 try catch 机制 异常

往期回顾

[Java基础] 基本数据类型

[Java基础] 运算符

[Java基础] 流程控制

[Java基础] 面向对象编程

[Java基础] 集合框架

[Java基础] 输入输出流

[Java基础] 异常处理机制

[Java基础] Lambda 表达式

目录

什么是异常处理?

异常分类

检查型异常

非检查型异常(Unchecked Exceptions)

运行时异常(RuntimeException)

错误(Error)

异常处理的主要语法

实战案例

示例代码

代码解释

处理异常的最佳实践


什么是异常处理?

Java中的异常处理是一种用于处理程序执行期间错误的机制。它允许开发者编写能够优雅地处理错误情况的健壮代码。Java的异常处理基于“抛出-捕获”模型,即当发生错误时,会创建一个表示该错误的异常对象,并将其从错误发生的地方抛出;然后,这个异常可以由专门的代码块(称为异常处理器)捕获并处理。

异常分类

检查型异常

检查型异常(Checked Exception)是指在编译时期就需要被捕获或声明的异常。这些异常是那些通常可以通过合理的编程逻辑来预防或处理的异常。如果方法可能抛出检查型异常,而调用该方法的代码没有捕获(try-catch)这个异常,或者没有在方法签名中通过throws关键字声明这个异常,编译器将报错。

以下是一些常见的检查型异常:

  • IOException:处理输入输出操作时可能抛出的异常,例如读写文件或网络通信。
  • SQLException:处理数据库操作时可能抛出的异常,例如执行SQL语句时出错。
  • ClassNotFoundException:使用Class.forName()方法动态加载类时,如果找不到指定的类,则抛出此异常。
  • InterruptedException:当一个线程在等待、睡眠或尝试执行一个阻塞操作时,另一个线程中断了当前线程,则抛出此异常。
  • ParseException:解析字符串为日期、数字等时,如果字符串格式不正确,则抛出此异常(具体实现可能因类库而异,例如java.text.ParseException)。
  • InvocationTargetException:在使用反射调用方法时,如果底层方法抛出异常,则通过此异常包装并抛出。
  • NoSuchMethodException IllegalAccessException:在使用反射访问方法或字段时,如果找不到指定的方法或没有访问权限,则抛出这些异常。
  • FileAlreadyExistsException:在创建新文件时,如果文件已经存在,则抛出此异常(具体实现可能因类库而异,例如java.nio.file.FileAlreadyExistsException)。
  • SocketException:处理网络套接字操作时可能抛出的异常,例如连接失败或套接字错误。
  • UnknownHostException:根据主机名解析IP地址时,如果无法找到主机名对应的IP地址,则抛出此异常。

非检查型异常(Unchecked Exceptions)

非检查型异常(Unchecked Exception)通常指的是RuntimeException及其子类,以及Error类及其子类。这些异常在编译时不会被强制要求处理,即可以不使用try-catch块捕获,也不需要在方法签名中通过throws关键字声明。然而,尽管编译器不强制要求处理这些异常,但在实际编程中,合理地处理这些异常仍然是非常重要的,以保证程序的健壮性和稳定性。下面会列举下常见的RuntimeExceptionError

运行时异常(RuntimeException)

  • NullPointerException
    • 当程序尝试在需要对象实例的地方使用 null 时抛出。
    • 例如:String s = null; s.length();
  • ArrayIndexOutOfBoundsException
    • 当数组索引超出其有效范围时抛出。
    • 例如:int[] array = {1, 2, 3}; int value = array[3];
  • IllegalArgumentException
    • 当传递给方法的参数不合适时抛出。
    • 例如:public void divide(int a, int b) { if (b == 0) throw new IllegalArgumentException("除数不能为零"); }
  • IllegalStateException
    • 当对象处于不适当的状态时抛出。
    • 例如:在一个尚未初始化的对象上调用某些方法。
  • ArithmeticException
    • 当发生算术错误时抛出,如除以零。
    • 例如:int result = 1 / 0;
  • ClassCastException
    • 当尝试将对象强制转换为不兼容的类型时抛出。
    • 例如:Object obj = new String("Hello"); Integer i = (Integer) obj;
  • NumberFormatException
    • 当尝试将字符串转换为数字但格式不正确时抛出。
    • 例如:int number = Integer.parseInt("abc");
  • IndexOutOfBoundsException
    • 当索引超出有效范围时抛出,类似于 ArrayIndexOutOfBoundsException,但更通用。
    • 例如:List<String> list = new ArrayList<>(); list.get(0);
  • StringIndexOutOfBoundsException
    • 当字符串索引超出有效范围时抛出。
    • 例如:String s = "hello"; char c = s.charAt(5);
  • NegativeArraySizeException
    • 当尝试创建具有负大小的数组时抛出。
    • 例如:int[] array = new int[-1];
  • UnsupportedOperationException
    • 当请求的操作不支持时抛出。
    • 例如:在不可修改的集合上尝试添加元素。
  • SecurityException
    • 当安全策略被违反时抛出。
    • 例如:尝试执行受限制的操作。
  • ConcurrentModificationException
    • 当检测到并发修改时抛出,通常发生在迭代器遍历集合时集合被修改。
    • 例如:List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); for (String s : list) { list.remove(s); }

错误(Error)

Error 类及其子类表示严重的系统级问题,这些问题通常表示虚拟机(JVM)本身或系统资源的问题。与异常不同,错误通常是不可恢复的,因此通常不需要在代码中捕获和处理这些错误。然而,了解常见的错误类型有助于理解程序中可能出现的问题。

以下是一些常见的 Error 类及其子类:

  • OutOfMemoryError
    • 当Java虚拟机无法分配新的对象,因为没有足够的内存可用时抛出。
    • 例如:创建一个非常大的数组或大量对象时,可能会导致此错误。
  • StackOverflowError
    • 当一个方法调用栈深度超过虚拟机限制时抛出。
    • 通常由无限递归引起。
  • NoClassDefFoundError
    • 当运行时系统试图加载一个类,但在类路径中找不到该类的定义时抛出。
    • 通常是因为类路径配置错误或依赖库缺失。
  • LinkageError
    • 表示某些链接操作失败,例如类的定义在加载时发生了不一致。
    • 子类包括 IncompatibleClassChangeErrorNoSuchFieldErrorNoSuchMethodError
  • IncompatibleClassChangeError
    • 当类的定义在加载时与其先前的定义不兼容时抛出。
    • 例如,一个接口在加载时变成了一个类。
  • NoSuchFieldError
    • 当试图访问一个不存在的字段时抛出。
    • 通常是因为类的结构在编译和运行时发生了变化。
  • NoSuchMethodError
    • 当试图调用一个不存在的方法时抛出。
    • 通常是因为类的结构在编译和运行时发生了变化。
  • AssertionError
    • 当断言失败时抛出。
    • 断言通常用于调试目的,确保某些条件在运行时为真。
  • ThreadDeath
    • 当线程被终止时抛出。
    • 通常由 Thread.stop() 方法调用引起,但不推荐使用该方法。
  • UnknownError
    • 表示一个未知的错误,通常表示JVM内部的问题。
  • VirtualMachineError
    • 表示JVM本身出现问题。
    • 子类包括 OutOfMemoryErrorStackOverflowError

异常处理的主要语法

  • try 块:用于封装可能抛出异常的代码。如果在 try 块中发生异常,则控制将转移到与之匹配的 catch 块。
  • catch 块:用于捕获 try 块中抛出的异常。每个 try 块可以有一个或多个 catch 块,用来指定可以捕获哪些类型的异常。
  • finally 块:无论是否发生异常,finally 块中的代码都会被执行。通常用于释放资源,如关闭文件或网络连接等。
  • throw 关键字:用于显式抛出一个异常对象。
  • throws 关键字:用于声明一个方法可能会抛出的异常。这可以是编译器强制要求的方法(检查型异常),也可以是可选声明的(运行时异常)。
  • 自定义异常:可以通过继承 Exception 或其子类来创建自己的异常类型。

实战案例

下面是一个完整的Java异常处理案例,它展示了如何使用trycatchfinallythrowsthrow关键字来处理异常。这个例子模拟了一个简单的文件读取操作,同时包含了一些自定义异常的处理。

示例代码

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileReadExample {

    public static void main(String[] args) {
        try {
            readAndProcessFile("example.txt");
        } catch (FileNotFoundException e) {
            System.err.println("文件未找到: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("读取文件时发生错误: " + e.getMessage());
        } catch (CustomException e) {
            System.err.println("自定义异常: " + e.getMessage());
        }
    }

    public static void readAndProcessFile(String fileName) throws FileNotFoundException, IOException, CustomException {
        BufferedReader reader = null;
        try {
            // 尝试打开文件
            reader = new BufferedReader(new FileReader(fileName));
            String line;
            // 逐行读取文件内容
            while ((line = reader.readLine()) != null) {
                processLine(line);
            }
        } catch (FileNotFoundException e) {
            // 文件未找到时的处理
            throw e; // 重新抛出异常
        } catch (IOException e) {
            // 读取文件时发生其他I/O错误
            throw e;
        } catch (CustomException e) {
            // 处理自定义异常
            throw e;
        } finally {
            // 无论是否发生异常,都会执行finally块
            if (reader != null) {
                try {
                    reader.close(); // 关闭文件流
                } catch (IOException e) {
                    System.err.println("关闭文件流时发生错误: " + e.getMessage());
                }
            }
        }
    }

    public static void processLine(String line) throws CustomException {
        // 模拟处理每一行数据
        if (line == null || line.isEmpty()) {
            throw new CustomException("空行或无效行: " + line);
        }
        System.out.println("处理行: " + line);
    }
}

//自定义异常
class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

代码解释

  • 导入必要的类
    • BufferedReaderFileReader 是用于文件读取的类。
    • IOException 是一个检查型异常,用于处理输入输出操作中的错误。
  • 主方法 (main 方法):
    • 调用 readAndProcessFile 方法来读取和处理文件。
    • 使用 try 块来包裹可能抛出异常的代码。
    • 捕获并处理 FileNotFoundExceptionIOExceptionCustomException
  • readAndProcessFile 方法
    • 创建一个 BufferedReader 对象,用于读取文件。
    • 使用 try 块来包裹可能抛出异常的代码。
    • 捕获并处理 FileNotFoundExceptionIOExceptionCustomException
    • 使用 throw 关键字重新抛出异常,以便在 main 方法中进一步处理。
    • 使用 finally 块来确保文件流在任何情况下都被关闭。
  • processLine 方法
    • 模拟处理每一行数据。
    • 如果行为空或无效,抛出自定义异常 CustomException
  • 自定义异常类 (CustomException):
    • 继承自 Exception 类。
    • 提供一个构造函数来设置异常消息。

处理异常的最佳实践

  • 尽量捕获具体的异常:避免捕获所有异常(如 catch (Exception e)),而应尽可能捕获具体的异常类型,这样可以更准确地处理特定错误。
  • 不要忽略异常:捕获到异常后应该做适当的处理,而不是简单地忽略它。
  • 使用 finally 块释放资源:确保无论是否发生异常,都能正确地释放资源。
  • 记录异常信息:在捕获异常后,记录异常信息可以帮助后续的问题排查。
  • 避免过度使用异常:异常处理机制虽然强大,但不应该用作常规流程控制结构。过度使用异常会影响程序性能。

标签:Java,处理,抛出,try,catch,机制,异常
From: https://blog.csdn.net/MCC_MCC_MCC/article/details/143024703

相关文章

  • java计算机毕业设计springboot+vue小区物业管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着城市化进程的加速,住宅小区的规模不断扩大,小区内的管理事务日益繁杂。传统的物业管理方式依赖人工操作,效率低下且容易出错。在信息技术飞速发......
  • java计算机毕业设计广告系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着互联网的迅猛发展,广告行业发生了翻天覆地的变化。广告形式和载体日益多样化,从传统的报纸、杂志、电视到如今无处不在的互联网广告等1。海量......
  • java基于springboot的在线教学平台(源码+vue+部署文档+前后端分离等)
    收藏关注不迷路!!......
  • Java虚拟机(JVM)(7)—— 垃圾回收(1)
    文章目录前言一、方法区的回收二、垃圾判别阶段算法1、引用计数法2、可达性分析算法GCRoots对象三、常见的引用对象1、强引用2、软引用软引用的使用方法3、弱引用4、虚引用和终结器引用四、垃圾回收算法1、垃圾回收算法的评价标准2、标记清除算法3、复制算法3、......
  • 深度讲解Java中的面对象,通俗易懂
    目录1.封装(Encapsulation)2.继承(Inheritance)3.多态(Polymorphism)4.抽象(Abstraction)总结在Java中,“面向对象编程”(Object-OrientedProgramming,简称OOP)是核心概念之一。它通过使用类和对象来组织代码,允许程序员创建可以模拟现实世界事物的代码结构。Java中的面向对象编......
  • python异常与模块
    1.了解异常什么是异常呢?当检测到一个错误时,python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”,也就是我们常说的bug像这样,计算机会告诉你出错的是哪一行代码以及出现错误的问题所在FileNotFoundError:文件未找到Nosuchfileordirectory:文......
  • 基于Java数据库管理系统的毕业设计论文
    摘要数据库管理系统是一个快速分析数据、方便管理者管理所有数据的后台操作系统,所以将传统的图书管理方式彻底的解脱出来,可以提高管理员的工作效率,减轻管理员以往繁忙的工作,减小出错的概率。从而使人们有更多时间来获取信息、了解信息、掌握信息。数据库的开发主要包括后台......
  • 反射机制及应用
    反射机制是指程序在运行时动态地获取类的信息、创建对象、访问对象的属性和调用对象的方法的一种能力。它使得程序能够在运行时检查和修改自身的结构。这种机制广泛应用于Java等编程语言,特别是在框架设计、序列化、依赖注入等场景中。反射机制的基本特性动态加载类:可以在......
  • 【最新Java必过毕设选题】基于SSM的医院门诊互联电子病历管理信息系统(源码+万字LW+答
    作品简介 Hi,各位同学好呀!今天向大家分享一个最新完成的高质量毕业设计项目作品基于SSM的XXX管理系统项目评分(最低0分,满分5分)难度系数:3分工作量:5分创新点:3分界面美化:5分使用技术前端:html/js/css/vue后端:ssm数据库:MySql服务器:apache-tomcat编译器:Int......
  • 【最新Java必过毕设选题】基于微信小程序的智能停车场管理小程序(源码+万字LW+答辩PPT)
    作品简介 Hi,各位同学好呀!今天向大家分享一个最新完成的高质量毕业设计项目作品基于ssm+uniapp的XXX微信小程序项目评分(最低0分,满分5分)难度系数:3分工作量:5分创新点:3分界面美化:5分使用技术小程序框架:uniapp小程序开发软件:HBuilderX小程序运行软件:微信开发者......