异常编程的安全卫士:error和exception

一个新学习Java编程的小伙伴告诉我,他把异常try起来了,但是最后怎么都进不了catch,问我咋回事,后面我帮他看了下,抛出的是OOM;这就尴尬了,这篇文章也是为了更加清晰的解释一下为啥OOM这种异常,他的try没有作用。

一、异常机制

程序出现错误后,程序执行的流程就不会按照我们的预定逻辑运行下去,这时程序的控制权会被转移到异常处理器进行异常处理。

1.1 一般程序错误会被分为三种

graph LR A(一般程序错误) B(编译时错误) C(运行时错误) D(逻辑错误) A --> B A --> C A --> D style B fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px

1、编译时错误 :程序没有遵循语法原则,编译程序自己会发现并且对我们进行提示,告知我们错误的原因以及发生错误的位置。(常犯错误);

2、运行时错误:在程序运行时期,运行程序的环境发生了无法执行该程序的情况;

3、逻辑错误:当程序没有按照我们预期的逻辑去执行时,程序可能会发生错误。

1.2 Java异常机制的主要作用如下

graph LR A(异常机制的作用) B(错误处理) C(异常传播) D(异常处理器) E(异常类型分类) F(异常信息) B1(通过捕获和处理异常 避免程序崩溃) C1(允许异常在适当的层次上被处理 并实现错误信息的传递和处理) D1(可以在发生异常时执行特定的操作) E1(异常类的继承和分类使开发人员能够根据具体情况选择适当的异常类型) F1(帮助调试和定位问题 快速识别和解决错误) A --> B --> B1 A --> C --> C1 A --> D --> D1 A --> E --> E1 A --> F --> F1 style B fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px style E fill:#98FB98,stroke:#98FB98,stroke-width:2px style F fill:#B2FFFF,stroke:#B2FFFF,stroke-width:2px style B1 fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C1 fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D1 fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px style E1 fill:#98FB98,stroke:#98FB98,stroke-width:2px style F1 fill:#B2FFFF,stroke:#B2FFFF,stroke-width:2px

1、错误处理:异常机制允许开发人员识别和处理可能导致程序出错的情况。当发生错误或异常时,程序可以捕获并处理异常,而不是终止执行。这样可以避免程序崩溃,并提供更好的用户体验。

2、异常传播:异常机制允许异常在方法调用堆栈中传播。当方法内部发生异常时,它可以选择捕获该异常并处理,或者将异常传播给调用它的方法。这样可以实现错误信息的传递和处理,并允许异常在适当的层次上被处理。

3、异常处理器 :Java的异常机制使用try-catch语句块来捕获和处理异常。通过编写相应的异常处理器,可以在发生异常时执行特定的操作,例如记录错误日志、恢复正常状态、显示错误信息或向用户提供友好的错误提示。

4、异常类型分类:Java的异常机制使用异常类来表示不同类型的异常。异常类可以根据异常的类型和严重程度进行继承和分类。这样,开发人员可以根据具体情况选择适当的异常类型,并编写相应的处理代码。

5、异常信息:异常机制提供了丰富的异常信息,包括异常类型、错误消息和异常发生的位置。这些信息对于调试和定位问题非常有帮助,可以帮助开发人员快速识别和解决错误。

二、异常的组成结构

先画了张图,清晰的表达了一下Java异常的组成结构,下面我们来详细认识一下他们:

2.1 Error 程序无法处理的错误

程序无法处理的错误,在运行应用程序时出现较严重的问题,Error是一种表示严重错误和不可恢复的异常情况的类型。

Error通常指示了虚拟机(JVM)或运行时环境发生了一些严重的问题,无法通过代码进行恢复。与普通的异常(Exception)不同,Error 一般不应该被捕获和处理,因为它们表示了无法修复的系统级问题。

这些错误通常是由于严重的系统问题、配置错误、资源限制或者代码逻辑错误引起的,无法通过代码进行处理或修复。当出现这些错误时,通常建议采取适当的措施来解决问题,例如增加系统资源、修复代码逻辑或重新配置系统环境。

以下是一些常见的Java Error

graph LR A(常见的Java Error) B(OutOfMemoryError 内存溢出错误) C(StackOverflowError 栈溢出错误) D(NoClassDefFoundError 类未找到错误) E(LinkageError 链接错误) F(AssertionError 断言错误) A ---> B A ---> C A ---> D A ---> E A ---> F style B fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px style E fill:#98FB98,stroke:#98FB98,stroke-width:2px style F fill:#B2FFFF,stroke:#B2FFFF,stroke-width:2px
  • OutOfMemoryError(内存溢出错误):当程序尝试申请更多的内存空间,而可用内存不足时,会抛出该错误。这可能是由于程序中存在内存泄漏、资源使用不当或者系统配置不当等原因导致的。

  • StackOverflowError(栈溢出错误):当方法调用的递归层次过深,导致方法调用栈无法容纳更多的方法调用时,会抛出该错误。通常是由于无限递归调用或者方法嵌套层次过深引起的。

  • NoClassDefFoundError(类未找到错误):当程序在运行时无法找到所需的类或接口定义时,会抛出该错误。这可能是由于类路径配置错误、类文件丢失或者版本不匹配等原因导致的。

  • LinkageError(链接错误) :当在类的链接阶段发生错误时,会抛出该错误。例如,当一个类依赖的其他类发生了不兼容的变化或者无法找到时,就会抛出LinkageError

  • AssertionError(断言错误) :当断言语句失败时,会抛出该错误。断言通常用于调试和测试中,用于检查程序的内部状态和约束条件是否满足,如果断言失败,就会抛出AssertionError

2.2 Exceprion 程序本身可以处理的异常

Java中,Exception 是一种表示程序运行期间出现异常情况的类。与Error不同,Exception通常表示可捕获和处理的异常情况,可以通过适当的代码来处理这些异常,以保证程序的正常执行

Java中的Exception分为两种类型:Checked Exception(受检异常)和Unchecked Exception(非受检异常)。

graph LR A(Exception的类型) B(Checked Exception) C(Unchecked Exception) D(受检异常) E(非受检异常) F(非运行时异常) G(运行时异常) A ---> B ---> D ---> F A ---> C ---> E ---> G style B fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px style E fill:#98FB98,stroke:#98FB98,stroke-width:2px style F fill:#B2FFFF,stroke:#B2FFFF,stroke-width:2px style G fill:#ADD8E6,stroke:#ADD8E6,stroke-width:2px

2.2.1 Checked Exception 受检异常

受检异常又叫非运行时异常,这些异常在代码中必须进行显式处理,否则编译器会报错。受检异常通常表示程序可能遭遇到外部因素导致的错误或异常情况,需要开发人员在代码中进行处理。

例如

graph LR A(非运行时异常) B(IOException 输入输出异常) C(SQLException SQL异常) D(ClassNotFoundException 类未找到异常) E(表示在读写文件 网络通信等输入输出操作中可能发生的问题) F(表示在数据库操作中可能发生的问题 如连接错误 查询错误等) G(表示在尝试加载类时找不到对应的类) A --> B --> E A --> C --> F A --> D --> G style B fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px style E fill:#98FB98,stroke:#98FB98,stroke-width:2px style F fill:#B2FFFF,stroke:#B2FFFF,stroke-width:2px style G fill:#ADD8E6,stroke:#ADD8E6,stroke-width:2px

2.2.2 Unchecked Exception 非受检异常

非受检异常又叫运行时异常,这些异常在代码中不需要显式处理,编译器不会强制要求处理它们。通常,非受检异常表示程序内部错误或逻辑错误,可以通过代码改进来避免。

例如

graph LR A(运行时异常) B(NullPointerException 空指针异常) C(ArrayIndexOutOfBoundsException 数组越界异常) D(IllegalArgumentException 非法参数异常) E(表示尝试访问空对象引用时发生的异常) F(表示尝试访问数组中不存在的索引位置时发生的异常) G(表示传递给方法的参数不符合预期要求时发生的异常) A --> B --> E A --> C --> F A --> D --> G style B fill:#FFC0CB,stroke:#FFC0CB,stroke-width:2px style C fill:#FFA07A,stroke:#FFA07A,stroke-width:2px style D fill:#FFFFE0,stroke:#FFFFE0,stroke-width:2px style E fill:#98FB98,stroke:#98FB98,stroke-width:2px style F fill:#B2FFFF,stroke:#B2FFFF,stroke-width:2px style G fill:#ADD8E6,stroke:#ADD8E6,stroke-width:2px

2.3 error 和exception 的区别

Java中,ErrorException是两种异常的基本分类,它们在以下几个方面有区别:

区别 Error Exception
继承关系 继承自Throwable 继承自Throwable
错误类型 严重的系统级问题,不可恢复错误 程序运行期间的可捕获和处理的异常情况
异常处理 通常不需要捕获和处理 需要进行异常处理,确保程序正常执行
受检与非受检 非受检异常 可分为受检异常和非受检异常
  • 继承关系Error类和Exception类都继承自Throwable类。但是,它们分别位于Throwable类的两个子类分支中。

  • 错误类型Error通常表示严重的系统级问题,表示虚拟机JVM)或运行时环境的不可恢复错误。它们通常指示了无法通过代码进行修复的问题,例如内存溢出、栈溢出等。而Exception表示程序运行期间的可捕获和处理的异常情况,可以通过适当的代码来处理这些异常。

  • 异常处理 :对于Error,通常不建议或不需要捕获和处理,因为它们表示了无法修复的系统级问题。相反,对于Exception,通常需要进行异常处理,以确保程序的正常执行。这可以通过try-catch语句块来捕获和处理异常,或者通过throws关键字在方法签名中声明可能抛出的异常。

  • 受检与非受检Exception分为受检异常(Checked Exception)和非受检异常(Unchecked Exception)两种类型。受检异常需要在代码中显式处理,编译器会强制要求进行处理;而非受检异常在代码中不需要显式处理,编译器不会强制要求处理。Error属于非受检异常,而一般的Exception则可以是受检异常或非受检异常,具体取决于其子类的定义。

三、总结

看完整篇文章,也就知道为啥最开始的OOM使用try抓不住了,哈哈。

一杯茶一包烟,一个BUG改一天!茶和烟在办公室一般不行,特别是现在都是无烟办公室的情况,但是一个BUG改一天确实很多时候的真实情况。

希望本文对您有所帮助。如果有任何错误或建议,请随时指正和提出。

同时,如果您觉得这篇文章有价值,请考虑点赞和收藏。这将激励我进一步改进和创作更多有用的内容。

感谢您的支持和理解!

相关推荐
Bonne journée5 分钟前
‌在Python中,print(f‘‘)是什么?
java·开发语言·python
潘多编程20 分钟前
Spring Boot微服务架构设计与实战
spring boot·后端·微服务
2402_8575893625 分钟前
新闻推荐系统:Spring Boot框架详解
java·spring boot·后端
2401_8576226627 分钟前
新闻推荐系统:Spring Boot的可扩展性
java·spring boot·后端
小懒编程日记32 分钟前
【数据结构与算法】B树
java·数据结构·b树·算法
hallo12839 分钟前
英文论文安全的免费查重网站
安全·论文
Y_3_742 分钟前
【回溯数独】有效的数独(medium)& 解数独(hard)
java·数据结构·windows·算法·dfs·回溯
RangoLei_Lzs1 小时前
C++模版SFIANE应用踩的一个小坑
java·开发语言·ui
北极无雪1 小时前
Spring源码学习(拓展篇):SpringMVC中的异常处理
java·开发语言·数据库·学习·spring·servlet
VXbishe1 小时前
(附源码)基于springboot的“我来找房”微信小程序的设计与实现-计算机毕设 23157
java·python·微信小程序·node.js·c#·php·课程设计