《Java 简易速速上手小册》第4章:Java 中的异常处理(2024 最新版)

news2025/1/21 22:01:27

在这里插入图片描述

文章目录

  • 4.1 异常类型和错误 - 遇见你的小怪兽
    • 4.1.1 基础知识
    • 4.1.2 重点案例:文件读取处理
    • 4.1.3 拓展案例 1:处理空指针异常
    • 4.1.4 拓展案例 2:捕获多个异常
  • 4.2 异常处理机制 - 穿上你的超级英雄斗篷
    • 4.2.1 基础知识
    • 4.2.2 重点案例:用户登录验证
    • 4.2.3 拓展案例 1:处理多个异常
    • 4.2.4 拓展案例 2:使用 finally 清理资源
  • 4.3 自定义异常 - 创造你自己的小怪兽
    • 4.3.1 基础知识
    • 4.3.2 重点案例:用户年龄验证
    • 4.3.3 拓展案例 1:账户余额不足
    • 4.3.4 拓展案例 2:数据格式验证

4.1 异常类型和错误 - 遇见你的小怪兽

在 Java 世界的深处,有两种主要的问题可能会打乱你代码的步伐:异常(Exception)错误(Error)。这就像是你在编程道路上会遇到的两种小怪兽。让我们先来了解一下它们,然后学习如何勇敢地面对它们。

4.1.1 基础知识

  • 异常(Exception):异常是程序运行时发生的问题,它们可能会打断程序的正常流程。Java 把异常分为两大类:

    • 检查型异常(Checked Exceptions):这些异常必须被显式地捕获或者通过方法签名声明抛出。它们通常是外部错误,比如文件未找到或者类未找到等,我们可以预见并提前处理这些异常。
    • 非检查型异常(Unchecked Exceptions):包括运行时异常(RuntimeException)和错误(Error)。运行时异常是编程错误,如空指针异常或数组越界。这些异常通常是可以避免的。
  • 错误(Error):错误是指在正常程序控制范围之外的问题,通常是由 JVM 系统内部错误或资源耗尽错误(如 StackOverflowErrorOutOfMemoryError)引起的。当发生错误时,Java 运行时环境(JRE)通常无法继续运行。

4.1.2 重点案例:文件读取处理

假设你正在编写一个程序来读取用户指定的文件,并打印其内容。这是一个典型的情景,可能会遇到 FileNotFoundException,这是一个检查型异常。

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileReaderDemo {
    public static void main(String[] args) {
        try {
            File file = new File("example.txt");
            Scanner scanner = new Scanner(file);
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
            }
            scanner.close();
        } catch (FileNotFoundException e) {
            System.out.println("An error occurred: File not found.");
            e.printStackTrace();
        }
    }
}

4.1.3 拓展案例 1:处理空指针异常

空指针异常(NullPointerException)是最常见的运行时异常之一,通常发生在试图调用或访问 null 对象的成员时。

public class NullPointerDemo {
    public static void main(String[] args) {
        try {
            String text = null;
            System.out.println(text.length());
        } catch (NullPointerException e) {
            System.out.println("Caught NullPointerException.");
        }
    }
}

4.1.4 拓展案例 2:捕获多个异常

在某些情况下,一个代码块可能会抛出多种类型的异常。Java 允许你在一个 catch 块中捕获多种类型的异常,这可以使代码更简洁。

import java.io.*;
import java.util.*;

public class MultiCatchDemo {
    public static void main(String[] args) {
        try {
            File file = new File("example.txt");
            Scanner scanner = new Scanner(file);
            System.out.println(10 / 0); // 故意制造除以零的异常
        } catch (ArithmeticException | FileNotFoundException e) {
            System.out.println("An error occurred: " + e.getMessage());
        }
    }
}

通过这些案例,我们可以看到 Java 异常处理的力量,它不仅可以帮助我们优雅地处理潜在的问题,还能确保即使在遇到异常时,我们的程序也能保持稳定运行。记住,勇敢地面对这些小怪兽,使用 Java 提供的工具来保护你的代码不受它们的影响。

在这里插入图片描述


4.2 异常处理机制 - 穿上你的超级英雄斗篷

在 Java 的世界里,异常处理机制就像是给你的代码穿上了一件超级英雄斗篷。它不仅保护你的程序不受意外的干扰,还确保了程序的健壮性和可靠性。让我们深入了解这件斗篷的超能力吧!

4.2.1 基础知识

  • try-catchtry 块让你尝试执行一段可能会抛出异常的代码。如果异常发生,catch 块会捕获这个异常,让你有机会处理它。

  • finally:无论是否发生异常,finally 块中的代码都会执行。这是清理资源的理想场所,比如关闭文件流或数据库连接。

  • throw:你可以使用 throw 关键字抛出一个异常。这通常用于指示方法遇到了无法自己处理的情况。

  • throws:当你的方法可能会抛出一个检查型异常,但不打算在当前方法内处理它时,你可以在方法签名中使用 throws 关键字声明这个异常。

4.2.2 重点案例:用户登录验证

假设我们正在编写一个用户登录的功能,需要验证用户输入的用户名和密码。如果用户输入不正确,我们会抛出一个异常。

class AuthenticationException extends Exception {
    public AuthenticationException(String message) {
        super(message);
    }
}

public class Login {
    public void authenticate(String username, String password) throws AuthenticationException {
        if (!"admin".equals(username) || !"password".equals(password)) {
            throw new AuthenticationException("Invalid username or password");
        }
        System.out.println("User authenticated successfully");
    }

    public static void main(String[] args) {
        Login login = new Login();
        try {
            login.authenticate("user", "1234");
        } catch (AuthenticationException e) {
            System.out.println(e.getMessage());
        }
    }
}

4.2.3 拓展案例 1:处理多个异常

在实际应用中,你可能需要处理多种类型的异常。Java 允许你在一个 try 块中捕获多个异常,并分别处理它们。

public class MultiExceptionHandling {
    public static void main(String[] args) {
        try {
            int[] numbers = new int[1];
            numbers[10] = 10; // 这会抛出 ArrayIndexOutOfBoundsException
            System.out.println(10 / 0); // 这会抛出 ArithmeticException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index is out of bounds!");
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero!");
        }
    }
}

4.2.4 拓展案例 2:使用 finally 清理资源

在处理文件或数据库连接时,确保资源最终被关闭是非常重要的。即使发生异常,finally 块也可以保证这一点。

import java.io.*;

public class FileReading {
    public static void main(String[] args) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("example.txt"));
            String line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
        } catch (IOException e) {
            System.out.println("Error reading file.");
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                System.out.println("Error closing the file.");
            }
        }
    }
}

通过这些案例,我们可以看到 Java 异常处理机制的强大之处。它不仅帮助你优雅地处理程序中的意外情况,还确保了资源的正确管理和释放。记住,掌握这些技巧,你的代码就穿上了超级英雄的斗篷,无惧任何挑战!

在这里插入图片描述


4.3 自定义异常 - 创造你自己的小怪兽

在 Java 的异常处理机制中,有时预定义的异常无法完全满足我们的需求。这时,Java 给了我们一个超能力——创造自己的异常。这就像是在你的代码世界中创造一个全新的小怪兽,完全按照你的规则行动。

4.3.1 基础知识

要创建一个自定义异常,你只需要定义一个类继承自 Exception 类(对于检查型异常)或 RuntimeException 类(对于非检查型异常)。这个新类就是你的自定义异常,你可以添加任何你需要的属性或方法。

// 检查型异常示例
public class MyCheckedException extends Exception {
    public MyCheckedException(String message) {
        super(message);
    }
}

// 非检查型异常示例
public class MyUncheckedException extends RuntimeException {
    public MyUncheckedException(String message) {
        super(message);
    }
}

4.3.2 重点案例:用户年龄验证

假设我们正在编写一个应用程序,需要验证用户的年龄是否满足特定条件。如果年龄不符合要求,我们将抛出一个自定义异常。

class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

public class AgeValidator {
    public void validateAge(int age) throws InvalidAgeException {
        if (age < 18) {
            throw new InvalidAgeException("Age less than 18 is not allowed");
        } else {
            System.out.println("Age is valid");
        }
    }

    public static void main(String[] args) {
        AgeValidator validator = new AgeValidator();
        try {
            validator.validateAge(16);
        } catch (InvalidAgeException e) {
            System.out.println(e.getMessage());
        }
    }
}

4.3.3 拓展案例 1:账户余额不足

在一个银行应用程序中,当用户尝试提取超过其账户余额的金额时,我们可以抛出一个自定义异常来处理这种情况。

class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

public class BankAccount {
    private double balance;

    public BankAccount(double balance) {
        this.balance = balance;
    }

    public void withdraw(double amount) throws InsufficientFundsException {
        if (balance < amount) {
            throw new InsufficientFundsException("Insufficient funds for withdrawal");
        } else {
            balance -= amount;
            System.out.println("Withdrawal successful");
        }
    }

    public static void main(String[] args) {
        BankAccount account = new BankAccount(100);
        try {
            account.withdraw(150);
        } catch (InsufficientFundsException e) {
            System.out.println(e.getMessage());
        }
    }
}

4.3.4 拓展案例 2:数据格式验证

在处理用户输入或文件读取时,我们可能需要验证数据的格式。如果数据格式不正确,抛出一个自定义异常是一个很好的做法。

class InvalidFormatException extends Exception {
    public InvalidFormatException(String message) {
        super(message);
    }
}

public class DataProcessor {
    public void processData(String data) throws InvalidFormatException {
        if (!data.matches("\\d+")) { // 简单的数字格式验证
            throw new InvalidFormatException("Data format is invalid");
        } else {
            System.out.println("Processing data: " + data);
        }
    }

    public static void main(String[] args) {
        DataProcessor processor = new DataProcessor();
        try {
            processor.processData("abc123");
        } catch (InvalidFormatException e) {
            System.out.println(e.getMessage());
        }
    }
}

通过这些案例,我们看到了自定义异常如何提高程序的可读性和健壮性。它们让异常处理变得更加具体和直观,帮助其他开发者(或未来的你)快速理解代码中可能发生的问题。创造你自己的小怪兽,让它们在需要时为你服务!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud-Feign:负载均衡(基于服务端)

7.Feign&#xff1a;负载均衡(基于服务端) 7.1 Feign简介 Feign是一个开源的声明式HTTP客户端&#xff0c;它可以简化HTTP API的调用过程。Feign的设计目标是使得使用者可以像调用本地方法一样调用远程服务&#xff0c;使得编写和维护HTTP客户端变得更加简单。类似controller…

2016-2022年哨兵影像的在线底图

有一个欧洲初创公司对哨兵影像进行了去云处理&#xff0c;制作了一个2016年-2022年的全球哨兵底图。目前底图通过wmts发布&#xff0c;可免费使用&#xff0c;无需搭梯子。 该数据的特点是&#xff1a; 很少的云覆盖&#xff0c;较少的条纹&#xff0c;色彩平衡 底图切片的网…

推荐高端资源素材图库下载平台整站源码

推荐高端图库素材下载站的响应式模板和完整的整站源码&#xff0c;适用于娱乐网资源网。该模板支持移动端&#xff0c;并集成了支付宝接口。 演示地 址 &#xff1a; runruncode.com/tupiao/19692.html 页面设计精美&#xff0c;不亚于大型网站的美工水准&#xff0c;并且用户…

如何对研究成果进行有效的专利布局

一、背景 研究成果通常是研究者、学者或创新者智力劳动的产物&#xff0c;如专利技术、设计、算法、新药物、研究方法等。通过专利申请、版权法、商标法、商业秘密等方式对其进行法律保护&#xff0c;确保研究者拥有对其成果的专有权&#xff0c;可以独享经济利益和控制权。 …

[LeetCode周赛复盘] 第 384 场周赛20240211

[LeetCode周赛复盘] 第 384 场周赛20240211 一、本周周赛总结100230. 修改矩阵1. 题目描述2. 思路分析3. 代码实现 100219. 回文字符串的最大数量1. 题目描述2. 思路分析3. 代码实现 100198. 匹配模式数组的子数组数目 II1. 题目描述2. 思路分析3. 代码实现 参考链接 一、本周…

GPT4:你是故意的吧!

请问下面选项中哪个是中文&#xff1f; A.Chinese B.英文 这是一个关于语言识别的问题。我们需要分析并确定所给选项中哪个表示中文。 对于选项A.Chinese&#xff1a;这个词本身表示“中文”或“中国的”。在多种语境中&#xff0c;它经常被用来指代中国的语言&#xff0c;即中…

京东组件移动端库的使用 Nut-UI

1.介绍 NutUI NutUI-Vue 组件库&#xff0c;基于 Taro&#xff0c;使用 Vue 技术栈开发小程序应用&#xff0c;开箱即用&#xff0c;帮助研发快速开发用户界面&#xff0c;提升开发效率&#xff0c;改善开发体验。 特性 &#x1f680; 80 高质量组件&#xff0c;覆盖移动端主…

Spring Boot 笔记 007 创建接口_登录

1.1 登录接口需求 1.2 JWT令牌 1.2.1 JWT原理 1.2.2 引入JWT坐标 1.2.3 单元测试 1.2.3.1 引入springboot单元测试坐标 1.2.3.2 在单元测试文件夹中创建测试类 1.2.3.3 运行测试类中的生成和解析方法 package com.geji;import com.auth0.jwt.JWT; import com.auth0.jwt.JWTV…

Spring Boot 笔记 010 创建接口_更新用户头像

1.1.1 usercontroller中添加updateAvatar&#xff0c;校验是否为url PatchMapping("updateAvatar")public Result updateAvatar(RequestParam URL String avatarUrl) {userService.updateAvatar(avatarUrl);return Result.success();} 1.1.2 userservice //更新头像…

BYTEVALUE 百为流控路由器远程命令执行漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

洛谷: P9749 [CSP-J 2023] 公路

思路: 贪心思想指的是在对问题求解的时候&#xff0c;总是能做出在当前看来是最好的选择,也就是说&#xff0c;如果要得到整个问题的最优答案&#xff0c;那么要求每一步都能做出最好的选择&#xff08;feihua&#xff09;。 在这道题里面&#xff0c;我们希望在来到第i站的时…

【十七】【C++】stack的简单实现、queue的常见用法以及用queue实现stack

stack的简单实现 #include <deque> #include <iostream> using namespace std; namespace Mystack {template<class T, class Container std::deque<T>>class stack {public:stack(): _c(){}void push(const T& data) {_c.push_back(data);}void …

论文阅读-One for All : 动态多租户边缘云平台的统一工作负载预测

论文名称&#xff1a;One for All: Unified Workload Prediction for Dynamic Multi-tenant Edge Cloud Platforms 摘要 多租户边缘云平台中的工作负载预测对于高效的应用部署和资源供给至关重要。然而&#xff0c;在多租户边缘云平台中&#xff0c;异构的应用模式、可变的基…

动态内存管理、柔性数组

动态内存分配的由来 我们已经掌握的内存开辟的方式&#xff1a; int val 20;//在栈空间上开辟四个字节 char arr[10] {0};//在栈空间上开辟10个字节的连续空间 上面开辟的空间大小是固定不可变的数组申请的大小也是确定了之后就不能改变 这里就引入了动态内存的开辟&#x…

FT2232调试记录(1)

FT2232调试记录 &#xff08;1&#xff09;获取当前连接的FTDI设备通道个数:&#xff08;2&#xff09;获取当前连接的设备通道的信息:&#xff08;3&#xff09;配置SPI的通道:&#xff08;4&#xff09;如何设置GPIO:&#xff08;5&#xff09;DEMO测试&#xff1a; #参考文档…

电路设计(15)——篮球赛24秒违例倒计时报警器的proteus仿真

1.设计要求 设计、制作一个篮球赛24秒违例倒计时报警器。要求&#xff1a; &#xff08;1&#xff09;具有倒计时功能。可完整实现从“24”秒开始依序倒计时并显示倒计时过程&#xff0c;显示时间间隔为1秒。 &#xff08;2&#xff09;具有消隐功能。当“24”秒倒计时…

网络安全的今年:量子、生成人工智能以及 LLM 和密码

尽管世界总是难以预测&#xff0c;但网络安全的几个强劲趋势表明未来几个月的发展充满希望和令人担忧。有一点是肯定的&#xff1a;2024 年将是非常重要且有趣的一年。 近年来&#xff0c;人工智能&#xff08;AI&#xff09;以令人难以置信的速度发展&#xff0c;其在网络安全…

LC 987. 二叉树的垂序遍历

987. 二叉树的垂序遍历 难度 : 困难 题目大意&#xff1a; 给你二叉树的根结点 root &#xff0c;请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言&#xff0c;其左右子结点分别位于 (row 1, col - 1) 和 (row 1, col 1) 。树的根结点位于 …

C++ :内存管理 newdelete

目录 内存区域划分 C的动态内存的管理方式 new new的基本使用方法 【注意事项】 delete 【注意】 new和delete操作自定义类型 operator new 和 operator delete 【关于自定义类型new申请内存】 【原理】 【调用顺序】 【连续开辟空间问题】 malloc/free和…

在面试中如何回复擅长vue还是react

当面试官问及这个问题的时候&#xff0c;我们需要思考面试官是否是在乎你是掌握vue还是react吗&#xff1f;&#xff1f;&#xff1f; 在大前端的一个环境下&#xff0c;当前又有AI人工智能的加持辅助&#xff0c;我们是不是要去思考企业在进行前端岗位人员需求的时候&#xf…