当前位置:首页 > 技术 > 正文内容

Java异常处理机制与自定义异常实现

访客 技术 2026年7月25日 1

异常类层次结构

在Java编程中,异常处理是构建健壮应用程序的关键组成部分。Java采用面向对象的方式管理异常,当程序执行过程中发生错误时,会创建异常对象并传递给运行时系统。

异常产生原因

Java程序中出现异常通常源于以下几种情况:

  1. JVM内部错误引发的系统异常
  2. 程序逻辑错误导致的运行时异常,如空指针引用、数组越界等
  3. 通过throw语句显式触发的异常,用于向调用者传递特定信息

常见异常场景包括:

  • 用户输入无效数据
  • 请求的文件不存在
  • 网络连接中断或内存溢出

异常类型分类

Java异常主要分为三类:

  1. 检查异常(Checked Exceptions):通常由用户错误或外部问题引起,程序员无法预见,必须在编译时处理。例如:文件不存在异常。

  2. 运行时异常(Runtime Exceptions):可由程序员避免的异常,编译器不强制要求处理。例如:空指针异常。

  3. 错误(Errors):不是异常,而是超出程序员控制的问题,通常不处理。例如:栈溢出错误。

异常类继承体系

所有异常类都继承自java.lang.Exception类,而Exception又是Throwable类的子类。Throwable还有一个子类Error,用于表示严重的系统错误。

异常类的两个主要子类:

  • IOException:处理输入输出相关异常
  • RuntimeException:处理程序运行时产生的异常

常用异常方法

Throwable类提供了几个关键方法:

  • printStackTrace():输出异常类型、性质、调用栈信息
  • getMessage():获取异常的具体描述信息
  • toString():返回异常的字符串表示

常见异常列表

非检查异常:

异常类 描述
ArithmeticException 算术运算错误,如除零操作
ArrayIndexOutOfBoundsException 数组索引越界
NullPointerException 空对象引用
IllegalArgumentException 非法参数传递
NumberFormatException 数字格式转换错误

检查异常:

异常类 描述
ClassNotFoundException 类未找到
IOException 输入输出异常
SQLException 数据库访问异常
InterruptedException 线程中断异常

异常处理关键字

throws关键字

throws用于声明方法可能抛出的异常,表示该方法不处理这些异常,而是将异常处理责任交给调用者。

语法格式:

返回值类型 方法名(参数列表) throws 异常类型1, 异常类型2 {
    // 方法实现
}

使用throws的典型场景:

  • 当前方法不知道如何处理特定异常
  • 希望将异常处理责任向上传递
  • 调用者需要根据异常类型采取不同处理策略

throw关键字

throw用于显式抛出异常对象,执行throw语句后,当前方法会立即终止,异常对象会被传递到调用栈的上一层。

if (参数 < 0) {
    throw new IllegalArgumentException("参数不能为负数");
}

异常捕获机制

try-catch-finally结构

try-catch-finally是Java异常处理的核心结构:

try {
    // 可能抛出异常的代码
} catch (异常类型1 变量名) {
    // 处理异常类型1的代码
} catch (异常类型2 变量名) {
    // 处理异常类型2的代码
} finally {
    // 无论是否发生异常都会执行的代码
}

执行规则:

  1. try块中没有异常:顺序执行try块和finally块,跳过catch块
  2. try块中抛出异常:执行匹配的catch块,然后执行finally块
  3. 多个catch块:按顺序匹配,父类异常的catch块必须在子类之后
  4. finally块:总是执行(除非调用System.exit())

代码示例

public class ExceptionDemo {
    private static String result = "";
    
    public static void processValue(int value) {
        try {
            if (value == 1) {
                throw new IllegalStateException("值不能为1");
            }
            result += "A";
        } catch (Exception e) {
            System.out.println(e.getMessage());
            result += "M";
            return;
        } finally {
            result += "C";
        }
        result += "G";
    }
    
    public static void main(String[] args) {
        processValue(0);
        processValue(1);
        System.out.println(result);
    }
}

输出结果:

值不能为1
ACGMC

自定义异常

创建自定义异常类

自定义异常需要遵循以下规则:

  1. 所有异常必须继承自Throwable类
  2. 检查异常需继承Exception类
  3. 运行时异常需继承RuntimeException类
// 检查异常
class BusinessException extends Exception {
    public BusinessException(String message) {
        super(message);
    }
}

// 运行时异常
class SystemRuntimeException extends RuntimeException {
    public SystemRuntimeException(String message) {
        super(message);
    }
}

自定义异常使用示例

public class CustomExceptionDemo {
    public static void main(String[] args) {
        try {
            validateInput(-5);
        } catch (BusinessException e) {
            System.out.println("捕获到业务异常: " + e.getMessage());
        }
        
        try {
            checkSystemCondition(10);
        } catch (SystemRuntimeException e) {
            System.out.println("捕获到系统异常: " + e.getMessage());
        }
    }
    
    // 抛出检查异常
    public static void validateInput(int value) throws BusinessException {
        if (value < 0) {
            throw new BusinessException("输入值不能为负数");
        }
        System.out.println("输入值有效: " + value);
    }
    
    // 抛出运行时异常
    public static void checkSystemCondition(int threshold) {
        if (threshold > 5) {
            throw new SystemRuntimeException("系统参数超出阈值: " + threshold);
        }
        System.out.println("系统参数正常: " + threshold);
    }
}

输出结果:

捕获到业务异常: 输入值不能为负数
系统参数正常: 10

自定义异常类应遵循命名规范,通常以"Exception"作为后缀,如"UserNotFoundException"、"InvalidParameterException"等,以清晰表达异常的用途。

通过合理使用异常处理机制和自定义异常,可以显著提高Java程序的健壮性和可维护性。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。