java:Java中的异常处理

目录

异常的概念与体系结构

异常的概念:

异常的体系结构:

异常的处理方式

防御式编程:

异常的抛出:

异常的捕获:

finally:

代码示例:

异常的处理流程

自定义异常类

举例: 


异常的概念与体系结构

异常的概念:

在程序中不正常行为称为异常,如算术异常、数组越界异常、空指针异常等。

例如:

public class ExceptionDemo {

    public static void main(String[] args) {
        // 示例算术异常
        try {
            int result = 10 / 0; // 除以0会抛出算术异常
        } catch (ArithmeticException e) {
            System.out.println("算术异常:" + e.getMessage());
        }

        // 示例数组越界异常
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[100]); // 访问数组越界会抛出数组越界异常
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界异常:" + e.getMessage());
        }

        // 示例空指针异常
        try {
            String str = null;
            System.out.println(str.length()); // 对空指针调用方法会抛出空指针异常
        } catch (NullPointerException e) {
            System.out.println("空指针异常:" + e.getMessage());
        }
    }
}

异常的体系结构:

        Throwable是异常体系的顶层类,派生出Error和Exception两个重要的子类,分为编译时异常和运行时异常。


异常的处理方式

防御式编程:

LBYL(Look Before You Leap):在操作之前进行充分的检查,事前防御型。例如,在代码中先检查条件,再执行操作,以避免异常情况的发生。

EAFP(It's Easier to Ask Forgiveness than Permission):先操作,遇到问题再处理,事后认错型。这种方式更关注正常流程,代码更清晰,容易理解。

异常的抛出:

使用throw关键字抛出异常对象,将错误信息告知给调用者。抛出的异常对象必须是Exception或其子类对象,根据异常类型不同,处理方式也不同。

异常的捕获:

通过try-catch捕获并处理异常,可以在catch块中对捕获到的异常进行具体处理。如果异常无法在当前方法中处理,可以继续向上抛出或交给调用者处理。

异常声明throws:在方法声明时使用throws关键字将异常抛给方法的调用者处理,提醒调用者处理异常。

finally:

finally块用于资源清理的扫尾工作,无论是否发生异常,finally中的代码都会被执行一般用于释放资源,确保资源得到正确释放。

代码示例:

public class ExceptionHandlingDemo {

    public static void main(String[] args) {
        // 防御式编程示例 - LBYL
        String str = null;
        if (str != null) {
            System.out.println(str.length()); // 不会执行,避免空指针异常
        }

        // 防御式编程示例 - EAFP
        int[] arr = {1, 2, 3};
        try {
            System.out.println(arr[100]); // 尝试访问数组越界
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界异常:" + e.getMessage());
        }

        // 异常的抛出示例
        try {
            validateAge(-5); // 抛出自定义异常
        } catch (IllegalArgumentException e) {
            System.out.println("年龄不能为负数:" + e.getMessage());
        }

        // 异常的捕获示例
        try {
            int result = divide(10, 0); // 抛出算术异常
        } catch (ArithmeticException e) {
            System.out.println("算术异常:" + e.getMessage());
        }

        // finally示例
        try {
            System.out.println("Try block");
        } finally {
            System.out.println("Finally block - resource cleanup");
        }
    }

    // 自定义异常类
    static void validateAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
    }

    // 抛出算术异常
    static int divide(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException("除数不能为0");
        }
        return a / b;
    }
}

在上述代码中,演示了防御式编程中的LBYL和EAFP方式,异常的抛出和捕获,以及finally块的使用。通过这些示例,展示了不同的异常处理方式在实际代码中的应用。


异常的处理流程

  • 程序首先执行try中的代码块
  • 如果try中的代码块出现异常,程序会立即跳转到对应的catch块进行异常处理
  • 如果找到匹配的异常类型,就会执行对应的catch块中的代码
  • 如果没有找到匹配的异常类型,异常会被向上抛出,继续传递给上层调用者
  • 无论是否找到匹配的异常类型,finally块中的代码都会被执行,用于进行资源清理等操作。
  • 如果异常一直向上传递到main方法仍未被处理,最终会交给JVM处理,导致程序异常终止。

下面是一个示例代码,演示了完整的异常处理流程:

public class ExceptionHandlingFlow {  

    public static void main(String[] args) {
        try {
            int result = divide(10, 0); // 抛出算术异常
        } catch (ArithmeticException e) {
            System.out.println("算术异常:" + e.getMessage());
            // 继续向上抛出异常
            throw e;
        } finally {
            System.out.println("finally块中的代码一定会执行");
        }
    }

    // 抛出算术异常
    static int divide(int a, int b) {
        try {
            if (b == 0) {
                throw new ArithmeticException("除数不能为0");
            }
            return a / b;
        } catch (ArithmeticException e) {
            System.out.println("捕获到算术异常:" + e.getMessage());
            // 继续向上抛出异常
            throw e;
        } finally {
            System.out.println("divide方法的finally块中的代码一定会执行");
        }
    }
}

运行结果:

在上述代码中,通过try-catch-finally块展示了完整的异常处理流程。无论是否出现异常,finally块中的代码都会被执行,用于进行必要的资源清理操作。这样可以确保程序在异常情况下也能够正常运行并保持稳定性。


自定义异常类

  • 自定义异常类继承自Exception或RuntimeException,用于表示实际开发中遇到的特定异常。
  • 可以实现带有String类型参数的构造方法,用于说明异常的原因。
  • 自定义异常通常继承自Exception或RuntimeException,分为受查异常和非受查异常。

举例: 

// 自定义用户名异常类,继承自Exception,表示用户名错误
class UserNameException extends Exception {
    public UserNameException(String message) {
        super(message);
    }
}

// 自定义密码异常类,继承自Exception,表示密码错误
class PasswordException extends Exception {
    public PasswordException(String message) {
        super(message);
    }
}

public class CustomExceptionExample {

    // 模拟用户登录,抛出自定义异常
    public static void login(String userName, String password) throws UserNameException, PasswordException {
        if (!userName.equals("admin")) {
            throw new UserNameException("用户名错误");
        }
        if (!password.equals("123456")) {
            throw new PasswordException("密码错误");
        }
        System.out.println("登录成功");
    }

    public static void main(String[] args) {
        try {
            login("admin", "12345"); // 模拟登录,抛出异常
        } catch (UserNameException e) {
            System.out.println("用户名异常:" + e.getMessage());
            // 可以在此处处理用户名异常
        } catch (PasswordException e) {
            System.out.println("密码异常:" + e.getMessage());
            // 可以在此处处理密码异常
        }
    }
}

在上述代码中,我们定义了两个自定义异常类UserNameExceptionPasswordException,分别用于表示用户名错误和密码错误的异常。这些异常类继承自Exception,表示受查异常,需要在方法声明中进行处理或抛出。在login方法中模拟用户登录过程,如果用户名或密码错误,则抛出相应的自定义异常。在main方法中通过try-catch块捕获并处理这些自定义异常,确保程序在异常情况下能够正常运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/566225.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Hadoop3.3.6】数据块副本放置策略及解析EditLog和FsImage

目录 一、摘要二、正文2.1 环境说明2.2 网络拓扑2.3 Hadoop副本放置策略介绍2.4 解析EditLog和Fsimage镜像文件三、小结一、摘要 通过解析存储于NameNode节点上的日志文件EditLog和镜像文件(元数据)Fsimage来反向验证HDFS的数据块副本存放策略,其目的是希望加深对Hadoop的数…

2024HVV在即| 最新漏洞CVE库(1.5W)与历史漏洞POC总结分享!

前言 也快到护网的时间了,每年的护网都是一场攻防实战的盛宴,那么漏洞库就是攻防红蓝双方人员的弹药库,红队人员可以通过工具进行监测是否存在历史漏洞方便快速打点,而蓝队则可以对资产进行梳理和监测历史漏洞,及时处理和修复,做好准备. 下面分享的…

【电控笔记5.4】pwm延迟

PWM延迟 1标准采样法 Td=MCU计算延迟+输出延迟 Tcon=电流控制周期 Ts=PWM载波周期 Td=1.5Ts(6.3节 ) 电流环跟PWM采样周期同步 2修改采样法

YOLOv5改进 | Conv篇 | 利用CVPR2024-DynamicConv提出的GhostModule改进C3(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是CVPR2024的最新改进机制DynamicConv其是CVPR2024的最新改进机制&#xff0c;这个论文中介绍了一个名为ParameterNet的新型设计原则&#xff0c;它旨在在大规模视觉预训练模型中增加参数数量&#xff0c;同时尽量不增加浮点运算&#x…

如何使用 ArcGIS Pro 快速为黑白地图配色

对于某些拍摄时间比较久远的地图&#xff0c;限于当时的技术水平只有黑白的地图&#xff0c;针对这种情况&#xff0c;我们可以通过现在的地图为该地图进行配色&#xff0c;这里为大家讲解一下操作方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微…

kafka 命令行使用 消息的写入和读取 quickstart

文章目录 Intro命令日志zookeeper serverkafka servercreate topic && describe topic Intro Kafka在大型系统中可用作消息通道&#xff0c;一般是用程序语言作为客户端去调用kafka服务。 不过在这之前&#xff0c;可以先用下载kafka之后就包含的脚本文件等&#xff0…

ChromaDB教程

使用 Chroma DB&#xff0c;管理文本文档、将文本嵌入以及进行相似度搜索。 随着大型语言模型 &#xff08;LLM&#xff09; 及其应用的兴起&#xff0c;我们看到向量数据库越来越受欢迎。这是因为使用 LLM 需要一种与传统机器学习模型不同的方法。 LLM 的核心支持技术之一是…

数据库管理-第173期 OceanBase一体化Plus多模融合(20240422)

数据库管理173期 2024-04-22 数据库管理-第173期 OceanBase一体化Plus多模融合&#xff08;20240422&#xff09;1 架构简化2 不止融合2.1 行列混存2.2 多维使用2.3 多模JOIN 3 展望 数据库管理-第173期 OceanBase一体化Plus多模融合&#xff08;20240422&#xff09; 作者&…

Skill Check: Building Blocks for an LLM Application

Skill Check: Building Blocks for an LLM Application

腾讯云轻量2核4G5M服务器优惠价格165元1年,2024年多配置报价单

腾讯云轻量2核4G5M服务器优惠价格165元1年。腾讯云服务器价格表2024年最新价格&#xff0c;轻量2核2G3M服务器61元一年、2核2G4M服务器99元1年&#xff0c;三年560元、2核4G5M服务器165元一年、3年900元、轻量4核8M12M服务器646元15个月、4核16G10M配置32元1个月、8核32G配置11…

vue-element-admin vue设置动态路由 刷新页面后出现跳转404页面Bug 解决方法

做项目时遇到的这个bug&#xff0c;因为除了跳404之外也没太大影响&#xff0c;之前就一直放着没管&#xff0c;现在项目基本功能实现了&#xff0c;转头处理了一下&#xff0c;现在在这里记录一下解决方法 这个bug的具体情况是&#xff1a;设置了动态路由之后&#xff0c;不同…

如何在PostgreSQL中使用索引覆盖扫描提高查询性能?

文章目录 解决方案1. 创建合适的索引2. 确保查询能够使用索引覆盖扫描3. 调整查询以利用索引覆盖扫描4. 监控和调优 示例代码1. 创建索引2. 编写查询3. 检查是否使用索引覆盖扫描4. 调整索引 总结 在PostgreSQL中&#xff0c;索引是提高查询性能的关键工具之一。索引允许数据库…

物理机中没有VMNet1和VMNet8虚拟网卡

控制面板——网络连接——网络适配器 VMware Network Adapter VMnet1 VMware Network Adapter VMnet8 如果没有这两个虚拟网卡&#xff0c;虚拟机的网络会出现问题 # 解决办法-恢复虚拟网卡默认设置 1、下载并打开ccleaner&#xff0c;ccleaner官网&#xff1a;CCleaner M…

【苍穹外卖】HttpClient-快速理解入门

目录 HttpClient-快速理解&入门1. 需求2. 如何使用3. 具体示例4. 大致优点5. 大致缺点 HttpClient-快速理解&入门 1. 需求 在平常访问服务器里面的资源的时候&#xff0c;我们通常是通过浏览器输入网址&#xff08;或者在浏览器点击某个连接&#xff09;这种方式&…

OpenCV杂记(2):图像拼接(hconcat, vconcat)

OpenCV杂记&#xff08;1&#xff09;&#xff1a;绘制OSD&#xff08;cv::getTextSize, cv::putText&#xff09;https://blog.csdn.net/tecsai/article/details/137872058 1. 简述 做图像处理或计算机视觉技术的同学都知道&#xff0c;我们在工作中会经常遇到需要将两幅图像拼…

Spring Boot中判断轨迹数据是否经过设置的打卡点,且在PGSQL中把点拼接成线,判断某个点是否在线上或在线的50米范围内

问题描述 轨迹数据判断是否经过打卡点&#xff0c;轨迹数据太多&#xff0c;循环判断的话非常消耗内存。解决办法只需要把所有轨迹数据点拼成了一条线&#xff0c;然后只需要循环打卡点即可&#xff0c;打卡点不多&#xff0c;一般不会超过100个&#xff0c;如果多的话&#x…

苹果手机远程打卡教程

关于苹果手机远程打卡教程之——有电脑零成本版 &#x1f4ce;个人主页&#xff1a;我的主页 &#x1f4ce;小白一枚&#xff0c;欢迎指教&#x1f44f; 嗨嗨嗨&#xff0c;今天来出一期iPhone实现远程打卡的教程&#xff0c;让我们可以随时随地的打卡wherever&#xff5e; 准…

shell进阶之正则表达式:字符转义(十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【深度学习】烟雾和火焰数据集,野外数据集,超大量数据集,目标检测,YOLOv5

标注了2w张数据集&#xff0c;是目标检测yolo格式的&#xff0c;有火焰、烟雾两个目标。 训练方法看这里&#xff1a; https://qq742971636.blog.csdn.net/article/details/138097481 打包 依据不一样的需求&#xff0c; 详情请查看 https://docs.qq.com/sheet/DUEdqZ2l…

在windows系统中安装kafka配置全步骤记录

在windows系统中安装kafka配置全步骤记录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可…