您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 
 订阅
JAVA入坑之异常处理
 
作者:烟雨平生9527

   次浏览      
 2023-4-20
 
编辑推荐:
本文主要介绍Java异常处理相关知识。希望能对遇到类似问题的同学有所帮助。
本文来自于CSDN,由火龙果软件Linda编辑、推荐。

一、程序错误

在Java程序中,错误通常分为三类:编译时错误、运行时错误和逻辑错误。

1.编译时错误:编译时错误是指在编译Java程序时发生的错误。这些错误通常是由于语法错误或类型不匹配等问题导致的。例如,下面的代码将无法通过编译,因为它试图将一个字符串赋值给一个整型变量:

int x = "hello"; // 编译时错误

 

2.运行时错误:运行时错误是指在程序运行过程中发生的错误。这些错误通常是由于程序中的异常情况导致的,例如除以零、空指针引用等。运行时错误会导致程序崩溃并抛出异常。例如,下面的代码将在运行时抛出ArithmeticException异常,因为它试图除以零:

int x = 10 / 0; // 运行
时错误,抛出ArithmeticException异常

3.逻辑错误:逻辑错误是指程序虽然能够正常编译和运行,但是其行为与预期不符。这些错误通常是由于程序员在编写代码时犯了逻辑错误导致的。例如,下面的代码本意是计算两个数的平均值,但由于程序员犯了一个简单的逻辑错误,导致结果不正确:

  1. int x = 10;
  2. int y = 20;
  3. int average = x + y /
    2; // 逻辑错误,应该写成 (x + y) / 2

二、异常

2.1概述

异常是程序执行期间发生的意外事件。它影响程序指令流,从而导致程序异常终止。

2.2产生原因

无效的用户输入

设备故障

网络连接丢失

物理限制(磁盘内存不足)

代码错误

打开一个不可用的文件

2.3Java 异常层次结构

从上图可以看到,Throwable类是层次结构中的根类。

请注意,层次结构分为两个分支:错误(Error)和异常(Exception)。

Error

Error表示不可恢复的情况,例如Java虚拟机(JVM)内存不足,内存泄漏,堆栈溢出错误,库不兼容,无限递归等。

错误通常是程序员无法控制的,我们不应该尝试处理错误。

出现严重的,无法恢复运行状态的错误,出现错误后一般只能进行详细的日志记录汇报

Exception

程序可以捕获并处理异常。

当方法内发生异常时,它将创建一个对象。该对象称为异常对象。

它包含有关异常的信息,例如异常的名称和说明以及发生异常时的程序状态。例如空指针访问 试图读取不存在的文件 网络连接中断

分类:受检(编译时)异常和非受检(运行时)异常

2.3.1非受检异常

非受检异常(运行时异常) 是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。 对于这类异常,可以不作处理或者加上逻辑判断。

运行中不应该出现而又出现的问题,此类异常一般是由于代码(逻辑)错误(不严谨)产生的,不应通过捕获异常处理,而应通过修正代码更正错误解决

2.3.2受检异常

是指要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求java程序必须捕获或声明所有编译时异常。 对于这类异常,如果程序不处理,可能会带来意想不到的结果。

一般为程序与程序控制之外的外部资源互交时,产生的错误 如文件无法读取,数据库无法访问,网络无法连接等 程序必须为可能出现的受检异常,提供异常处理程序,从而使程序可以继续运行而非停止崩溃

2.3.3常用异常:

三、异常处理机制

3.1概述

异常处理机制是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况,即超出程序正常执行流程的某些特殊条件。它让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。

调用栈Call Stack

调用栈(Call Stack)是计算机内部一种用来跟踪程序运行状态的数据结构,类似于人们在日常生活中的“记事本”,记录了程序在运行过程中每一个函数调用的位置、参数和返回值等信息。它是计算机科学中存储有关正在运行的子程序的消息的栈

3.2异常类型的实现

Java提供了3种主要的异常类型的实现

java.lang.Error,继承自Throwable,

非受检 java.lang.Exception,继承自Throwable,受检异常

java.lang.RuntimeException ,继承自Exception,运行时异常,非受检异常

java.lang.Throwable类,所有错误/异常的超类,仅Throwable及其子类对象可以被catch语句捕获

3.3异常处理的关键字:异常处理的关键字:

捕获异常:

try:执行可能产生异常的代码;

catch:捕获异常;

finally:无论是否发生异常,代码总被执行;

抛出异常:

throw:异常生成阶段,手动抛出异常对象;

声明异常:

throws声明方法可能要抛出的各种异常类

3.3.1try-catch Block

  1. public class Example {
  2. public static
    void
    main(String[] args) {
  3. int[] numbers = {1, 2, 3};
  4. try {
  5. // 尝试访问
    数组中不存在的元素
  6. System.out.println(numbers[3]);
  7. // 尝试将整数除以零
  8. System.out.println(3 / 0);
  9. } catch (ArrayIndexOut
    OfBoundsException e) {
  10. // 捕获并处理
    数组越界异常
  11. System.out.println
    ("数组越界!");
  12. } catch
    (ArithmeticException e) {
  13. // 捕获并处理
    算术异常
  14. System.out.
    println("算术异常!");
  15. }
  16. }
  17. }

 

将多个可能引发异常的代码 置于一个try块中 顺次声明多个catch与之关联

在try代码块与catch代码块之间,禁止定义其他代码

补充块变量的作用范围

块变量(也称为局部变量)是在代码块(如方法、循环或条件语句)中定义的变量。它们的作用范围仅限于定义它们的代码块。当代码块执行完毕后,块变量将不再可用。

  1. public class Example {
  2. public static void
    main(String[] args) {
  3. // 定义一个块变量
  4. int x = 10;
  5. if (x > 5) {
  6. // 定义另一个块变量
  7. int y = 20;
  8. System.out.
    println("x: " + x + ", y: " + y);
  9. }
  10. // 这里无法访问块变
    量 y,因为它已经超出了作用范围
  11. System.out.
    println("x: " + x);
  12. }
  13. }

补充Try-catch的执行顺序3.3.2Throwable 类常用方法

Throwable 类是 Java 语言中所有错误或异常的超类。它包含了一些常用的方法,可以帮助我们获取有关异常的信息,以下是一些常用的方法:

getMessage():返回此 throwable 的详细消息字符串。

printStackTrace():将此 throwable 及其追踪输出至标准错误流。这个方法会打印出异常的类型、详细消息以及异常发生时的堆栈信息。

toString():返回此 throwable 的简短描述。这个方法返回的字符串包含了异常的类型和详细消息。

getCause():返回此 throwable 的原因。如果原因不存在或未知,则返回 null。

  1. public class Example {
  2. public static void
    main(String[] args) {
  3. try {
  4. // 尝试将整数除以零
  5. System.out.
    println(3 / 0);
  6. } catch (ArithmeticException e) {
  7. // 获取并打印异常信息
  8. System.out.println("异常
    类型: "
    + e);
  9. System.out.println("异
    常信息: "
    + e.getMessage());
  10. System.out.println("堆栈信息: ");
  11. e.printStackTrace();
  12. System.out.println("原
    因: "
    + e.getCause());
  13. }
  14. }
  15. }

 

3.3.3finally 块

finally 块是与 try-catch 语句一起使用的一个可选代码块。它包含的代码无论是否发生异常都会被执行。通常,我们在 finally 块中放置一些清理资源的代码,例如关闭文件、释放内存等。

  1. public class Example {
  2. public static
    void
    main(String[] args) {
  3. try {
  4. // 尝试将整
    数除以零
  5. System.out.
    println(3 / 0);
  6. } catch (Arithmetic
    Exception e) {
  7. // 捕获并处理算术异常
  8. System.out.
    println("算术异常!");
  9. } finally {
  10. // 无论是否发
    生异常,都会执行这里的代码
  11. System.out.
    println("清理资源...");
  12. }
  13. }
  14. }

 

Try-catch-finally,执行顺序

包含return语句时,try-catch-finally的执行顺序

总结

Finally块仅用于释放资源,禁止参与业务逻辑的处理,块内禁止使用return语句

3.3.4try-with-resources语句

try-with-resources语句是Java 7中引入的一种try语句,旨在减轻开发人员释放try块中使用的资源的义务。它的全部想法是,开发人员无需担心仅在一个try-catch-finally块中使用的资源的资源管理。这是通过消除对finally块的需要而实现的,实际上,开发人员仅在关闭资源时才使用块。此外,使用try-with-resources的代码通常更清晰易读,因此使代码更易于管理,尤其是当我们处理许多try块时

  1. static String readFirstLine
    FromFile
    (String path)
    throws
    IOException {
  2. // try-with-resources语
    句,声明了两个资源:
    FileReader和BufferedReader
  3. try (FileReader fr
    = new FileReader(path);
  4. BufferedReader br
    = new BufferedReader(fr)) {
  5. // 从文件中读取第一行
  6. return br.readLine();
  7. }
  8. // 在try块结束后,
    资源会被自动关闭
  9. }

在这个例子中,声明在try-with-resources语句中的资源是一个FileReader和一个BufferedReader。这些资源的声明语句出现在紧跟在try关键字后面的括号内。在Java SE 7及更高版本中,类FileReader和BufferedReader实现了接口java.lang.AutoCloseable。由于在一个带有资源的try语句中声明了FileReader和BufferedReader实例,因此无论try语句是正常完成还是突然完成(由于方法BufferedReader.readLine抛出IOException),它们都将被关闭。

3.3.5 throw和throws 关键字

当方法没有捕获到可能发生的受检异常时,方法必须指定抛出受检异常 通过在方法声明添加throws子句,实现在方法抛出异常;在方法参数列表后(),方法体前{};方法抛出的所有异常使用“,”逗号分隔;

throw和throws是两个不同的关键字,它们都与异常处理有关。

throws关键字用于方法声明,用来指定该方法可能抛出的异常类型。它表示出现异常的一种可能性,但并不一定会发生这些异常。例如:

  1. public void myMethod()
    throws IOException
    {
  2. // 方法体
  3. }

而throw关键字用于方法体内,用来显式地抛出一个异常对象。执行throw则一定抛出了某种异常对象。例如:

  1. public void myMethod() {
  2. // ...
  3. throw new
    IOException("发生了IO异常");
  4. }

 

Java throws 和throw关键字

  1. import java.io.IOException;
  2. public class ThrowsExample {
  3. public static void
    main(String[] args) {
  4. try {
  5. myMethod();
  6. } catch (IOException e) {
  7. // 处理异常
  8. System.out.println
    ("捕获到了异常: " + e.getMessage());
  9. }
  10. }
  11. public static void
    myMethod() throws IOException {
  12. // 方法体
  13. // 如果在方法体中
    发生了IO异常,可以抛出
  14. throw new
    IOException("发生了IO异常");
  15. }
  16. }

 

简单来说,throws关键字用于声明一个方法可能抛出的所有异常信息,而throw则是指抛出的一个具体的异常类型。

注意

3.3.6自定义异常

在Java中,除了可以使用系统提供的异常类之外,还可以自定义异常类。自定义异常类通常用来表示程序中特定的异常情况。

  1. public class
    CustomExceptionExample
    {
  2. public static void
    main(String[] args) {
  3. int score = -5;
  4. try {
  5. if (score < 0 || score > 100) {
  6. throw new Invalid
    ScoreException
    ("分数
    值无效: "
    + score);
  7. }
  8. System.out.
    println("分数值有效: " + score);
  9. } catch (Invalid
    ScoreException e) {
  10. // 处理异常
  11. System.out.
    println(e.getMessage());
  12. }
  13. }
  14. }
  15. class InvalidScoreException
    extends Exception {
  16. public InvalidScoreException
    (String message) {
  17. super(message);
  18. }
  19. }

 

 

 
   
次浏览       
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析

最新活动计划
数据建模方法与工具 12-3[北京]
基于模型系统仿真与验证 12-14 [讲座]
白盒测试技术与工具实践 12-24[线上]
LLM大模型应用与项目构建 12-26[特惠]
UML和EA进行系统分析设计 12-20[线上]
SysML建模专家 1-16[北京]
 
 
最新文章
Java虚拟机架构
JVM——Java虚拟机架构
Java容器详解
Java进阶--深入理解ArrayList实现原理
Java并发容器,底层原理深入分析
最新课程
java编程基础到应用开发
JavaEE架构、 设计模式及性能调优
高性能Java编程与系统性能优化
SpringBoot&Cloud、JavaSSM框架
Spring Boot 培训
更多...   
成功案例
国内知名银行 Spring+SpringBoot+Cloud+MVC
北京 Java编程基础与网页开发基础
北京 Struts+Spring
华夏基金 ActiveMQ 原理
某民航公 Java基础编程到应用开发
更多...