Java 异常架构Exception(异常)

1. Exception 类的概述

在Java中,Exception类是Throwable类的直接子类之一。Throwable类是Java异常处理体系的根类,所有异常和错误都继承自它。Java的异常体系可以分为以下几个部分:

  • Throwable:所有异常和错误的基类。
      - Exception:程序可能捕获并处理的异常。
        - 受检异常(Checked Exception):必须显式捕获或声明抛出的异常。
        - 非受检异常(Unchecked Exception):包括运行时异常(RuntimeException)及其子类,不强制要求捕获或声明。
      - Error:由JVM生成的严重错误,通常不可恢复。
1.1 Exception的分类

Exception类进一步分为两大类:

  • 受检异常(Checked Exception)
      - 必须在代码中显式地捕获或声明抛出的异常。
      - 通常用于描述程序与外部资源(如文件、数据库、网络等)之间的交互中可能出现的异常情况。
      - 常见的受检异常包括IOExceptionSQLExceptionClassNotFoundException等。
  • 非受检异常(Unchecked Exception)
      - 继承自RuntimeException类,编译器不强制要求捕获或声明。
      - 通常用于描述编程错误,如逻辑错误、非法参数等。
      - 常见的非受检异常包括NullPointerExceptionArrayIndexOutOfBoundsExceptionIllegalArgumentException等。

2. 受检异常(Checked Exception)

受检异常是指在编译期间由编译器检查的异常。在Java中,如果某个方法可能会抛出受检异常,必须在方法声明中通过throws关键字显式声明,或者在方法内部通过try-catch块进行捕获处理。

2.1 受检异常的常见子类
  • IOException:表示在进行输入输出操作时发生的异常,常用于处理文件操作、网络通信等。
      
      java   public void readFile(String fileName) throws IOException {       BufferedReader reader = new BufferedReader(new FileReader(fileName));       String line = reader.readLine();       reader.close();   }  

  • SQLException:表示在访问数据库时发生的异常,通常在执行SQL语句时出现。

java   public void executeQuery(String query) throws SQLException {       Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/test", "user", "password");       Statement stmt = connection.createStatement();       ResultSet rs = stmt.executeQuery(query);       // 处理结果集       rs.close();       stmt.close();       connection.close();   }  

  • ClassNotFoundException:表示尝试加载某个类时,该类未找到的异常。通常出现在使用Class.forName方法时。

java   public void loadClass(String className) throws ClassNotFoundException {       Class<?> clazz = Class.forName(className);   }  

2.2 受检异常的处理

受检异常必须通过try-catch块捕获处理,或者在方法签名中使用throws关键字声明抛出。

public void processFile(String fileName) {try {readFile(fileName);} catch (IOException e) {e.printStackTrace();// 处理异常,例如通知用户或记录日志}
}

在这种情况下,readFile方法声明抛出IOException,因此调用该方法的processFile方法必须捕获或声明处理此异常。

3. 非受检异常(Unchecked Exception)

非受检异常是指不需要在代码中显式捕获或声明的异常。这类异常继承自RuntimeException,通常由程序中的逻辑错误或不合理的操作引发。

3.1 非受检异常的常见子类
  • NullPointerException:表示程序试图访问空引用对象的异常。这是Java中最常见的运行时异常之一。

java   public void printLength(String str) {       System.out.println(str.length()); // 如果str为null,会抛出NullPointerException   }  

  • ArrayIndexOutOfBoundsException:表示访问数组时,索引越界的异常。

java   public void printArrayElement(int[] arr, int index) {       System.out.println(arr[index]); // 如果index超出数组长度,会抛出ArrayIndexOutOfBoundsException   }  

  • IllegalArgumentException:表示方法接收到非法参数时抛出的异常。通常用于在方法开始时验证参数的合法性。

java   public void setAge(int age) {       if (age < 0) {           throw new IllegalArgumentException("Age cannot be negative");       }       this.age = age;   }  

3.2 非受检异常的处理

虽然编译器不强制要求处理非受检异常,但开发者仍应通过适当的方式处理这些异常,以提高代码的健壮性。

public void processInput(String input) {try {System.out.println(input.length());} catch (NullPointerException e) {System.out.println("Input cannot be null");}
}

通过捕获NullPointerException,程序可以在空输入的情况下给予用户适当的提示,而不是直接崩溃。

4. 自定义异常

Java允许开发者根据需求创建自定义异常。自定义异常通常继承自ExceptionRuntimeException,并可以添加额外的信息或行为。

4.1 自定义受检异常

如果你希望创建一个必须显式捕获或声明的异常,可以继承Exception类。

public class InvalidUserInputException extends Exception {public InvalidUserInputException(String message) {super(message);}public InvalidUserInputException(String message, Throwable cause) {super(message, cause);}
}

使用自定义异常:

public void processUserInput(String input) throws InvalidUserInputException {if (input == null || input.isEmpty()) {throw new InvalidUserInputException("User input cannot be null or empty");}// 处理输入
}
4.2 自定义非受检异常

如果你希望创建一个不强制要求捕获的异常,可以继承RuntimeException

public class InvalidConfigurationException extends RuntimeException {public InvalidConfigurationException(String message) {super(message);}public InvalidConfigurationException(String message, Throwable cause) {super(message, cause);}
}

使用自定义异常:

public void configure(String config) {if (config == null) {throw new InvalidConfigurationException("Configuration cannot be null");}// 配置操作
}

5. 异常处理的最佳实践

在处理异常时,开发者应遵循一些最佳实践,以确保代码的可读性、健壮性和维护性。

  1. 选择合适的异常类型:根据异常的性质选择适当的异常类型。对于可预见且需要强制处理的异常,使用受检异常;对于编程错误或非法操作,使用非受检异常。

  2. 避免通配符捕获:尽量避免使用catch (Exception e)catch (Throwable t)的通配符捕获方式,这会捕获所有类型的异常,可能隐藏潜在的问题。

  3. 清晰的异常信息:在抛出异常时,提供有意义的异常信息,以帮助调试和定位问题。

  4. 不要忽略异常:捕获异常后不要简单地忽略它们,应该采取适当的处理措施,如记录日志、通知用户或进行相应的补救措施。

  5. 合理使用finally块finally块用于清理资源(如关闭文件、网络连接等),确保无论是否发生异常,资源都能得到正确释放。Java 7及以后版本还可以使用try-with-resources语法自动管理资源。

6. 总结

Java的Exception类及其子类构成了Java异常处理的基础架构。通过了解受检异常和非受检异常的区别及其使用场景,开发者可以编写更健壮的代码,确保程序在异常情况下能够正确处理并恢复。

自定义异常允许开发者根据业务需求创建更加符合场景的异常类型,提升代码的可读性和可维护性。在实际开发中,合理处理异常不仅能提高程序的稳定性,还能增强用户体验。

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

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

相关文章

【Java|Stream流】不可变集合

文章目录 1.什么是不可变集合2.创建不可变集合的方式2.1 List类型2.2 Set2.3 Map 1.什么是不可变集合 不可变集合:不可以被修改的集合 不可变集合优点: 安全性 由于不可变集合不能被修改&#xff0c;所以可以安全地在多个线程之间共享&#xff0c;而不用担心被意外修改&#xf…

【kubernetes】Service 介绍和应用

一&#xff0c;Service介绍 四层代理是基于传输层&#xff08;第四层&#xff09;工作的代理&#xff0c;主要在传输层&#xff08;如TCP、UDP协议&#xff09;上转发和管理数据流 七层代理是基于应用层&#xff08;第七层&#xff09;工作的代理&#xff0c;能够对应用层协议…

# 利刃出鞘_Tomcat 核心原理解析(十)-- Tomcat 性能调优--2

利刃出鞘_Tomcat 核心原理解析&#xff08;十&#xff09;-- Tomcat 性能调优–2 二、Tomcat专题 - Tomcat性能调优 - 性能测试结果说明 1、压力性能测试 # 打开另一个终端&#xff0c;切换目录 [rootbogon ~]# cd /usr/local/tomcat# 进行压力性能测试[rootbogon tomcat]# …

JSON处理库 -- Fastjson

文章目录 一、json格式1.1 用途1.2 语法1.3 常见格式 二、fastjson常用类2.1 JSONObject2.2 JSONArray 三、序列化和反序列化3.1 默认序列化与反序列化3.2 序列化的扩展3.3 自定义序列化SerializeFilter3.4 JSONField 注解3.5 复习Jackson 一、json格式 1.1 用途 一种轻量级的…

浅谈SpringMvc的核心流程与组件

一、SpringMvc的核心流程 当发起请求时被前置的控制器(DispatcherServlet)拦截到请求&#xff0c;根据请求参数生成代理请求&#xff0c;找到请求对应的实际控制器&#xff0c;控制器处理请求&#xff0c;创建数据模型&#xff0c;访问数据库&#xff0c;将模型响应给中心控制…

threadLocal底层源码解析

分享链接&#xff1a; https://www.cnblogs.com/blissful/p/17929221.html

边缘计算与物联网中的深度学习应用

边缘计算与物联网中的深度学习应用 目录 一、引言 二、边缘计算基础 三、物联网基础 四、深度学习在物联网中的应用实例 五、总结 一、引言 随着物联网技术的不断发展&#xff0c;越来越多的设备和传感器被连接到互联网上&#xff0c;产生了海量的数据。这些数据需…

Android创建自己的内容提供器(ContentProvider)

文章目录 Android创建自己的内容提供器&#xff08;ContentProvider&#xff09;创建内容提供器的步骤新建MyProvider继承自ContentProvider内容URI的格式修改MyProvider中的代码MIME类型 Android创建自己的内容提供器&#xff08;ContentProvider&#xff09; 在上一节当中&a…

扑捉一只耿鬼(HTML文件)

图例&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>耿鬼</title><style>body {background: #fff;font-family: Comfortaa, sans-serif;}* {box-sizing:…

Unet改进12:添加PCONV||减少冗余计算和同时存储访问

本文内容:添加PCONV 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 为了设计快速的神经网络,许多工作都集中在减少浮点运算(FLOPs)的数量上。然而,我们观察到FLOPs的这种减少并不一定会导致类似程度的延迟减少。这主要源于低效率的每秒浮点操作数(FLOP…

Bean 的实例化(创建 | 获取)

Spring为Bean提供了多种实例化方式&#xff0c;包括如下4种方式&#xff1a; 第一种&#xff1a;通过构造方法实例化第二种&#xff1a;通过简单工厂模式实例化第三种&#xff1a;通过factory-bean实例化&#xff08;工厂方法模式实例化&#xff09;第四种&#xff1a;通过Fact…

盘点java8 stream中隐藏的函数式接口

shigen坚持更新文章的博客写手&#xff0c;记录成长&#xff0c;分享认知&#xff0c;留住感动。个人IP&#xff1a;shigen 提到函数式接口&#xff0c;最常见的就是lambda表达式&#xff0c;IDEA也有智能的提示&#xff1a; 最后改成这样的就是最简洁的、IDEA希望的风格&#…

Android UI绘制原理:UI的绘制流程是怎么样呢?为什么子线程不能刷新UI呢?讲解大体的流程是怎么样的

目录&#xff1a; 一、 为什么要学习android UI绘制原理呢&#xff1f;对我们有什么帮助&#xff1f; 1.解决复杂布局问题&#xff1a;了解UI绘制原理可以帮助我们更好地理解和解决布局问题&#xff0c;比如使用自定义View、优化布局层级等。 2.知道何时触发布局&#xff08;…

Java中的阻塞队列BlockingQueue

阻塞队列简介 阻塞队列是一个支持两个附加操作的队列 -> 支持阻塞的插入方法&#xff1a;当队列满时&#xff0c;队列会阻塞插入元素的线程&#xff0c;直到队列不满支持阻塞的移除方法&#xff1a;意思是在队列为空时&#xff0c;获取元素的线程会等待队列为非空 ->这…

【AI大模型】基于docker部署向量数据库Milvus和可视化工具Attu详解步骤

&#x1f680; 作者 &#xff1a;“大数据小禅” &#x1f680; 文章简介 &#xff1a;本专栏后续将持续更新大模型相关文章&#xff0c;从开发到微调到应用&#xff0c;需要下载好的模型包可私。 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 目…

zdppy_cache缓存框架升级,支持用户级别的缓存隔离,支持超级管理员管理普通用户的缓存

启动服务 import zdppy_api as api import zdppy_cachekey1 "admin" key2 "admin"app api.Api(routes[*zdppy_cache.zdppy_api.cache(key1, key2, api) ])if __name__ __main__:import zdppy_uvicornzdppy_uvicorn.run(app, host"0.0.0.0",…

TEngine框架之HybridCLR代码热更

自HybridCLR热更方案出现以来&#xff0c;像之前的主流toLua/xLua/ILRuntime瞬间不香了&#xff0c;算是跨世代的产物引起业界不小的轰动。HybridCLR是一个特性完整、零成本、高性能、低内存的近乎完美的Unity全平台原生c#热更新解决方案。想要详细了解HibirdCLR原理和使用的&a…

初爽Stream流

体验Stream流的作用&#xff1a; 需求&#xff1a; 按照下面的要求完成集合的创建和遍历 创建一个集合&#xff0c;存储多个字符串元素 要求&#xff1a; 1.把所有以“张”开头的元素存储到新集合中 2.把“张”开头的&#xff0c;长度为3的元素再存储到新集合中 3.遍历打…

【C++ | 设计模式】代理模式的详解与实现

1. 概念 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;用于控制对对象的访问。它通过引入代理对象&#xff0c;间接地操作目标对象&#xff0c;从而实现对目标对象的控制。代理模式的核心思想是通过代理对象来控制对目标对象的访问。代理对…

kubenetes--资源调度

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 出自B站博主教程笔记&#xff1a; 完整版Kubernetes&#xff08;K8S&#xff09;全套入门微服务实战项目&#xff0c;带你一站式深入掌握K8S核心能…