Java异常的介绍与处理

一、异常与错误(Error)的区别

        异常(Exception)和错误(Error)都是指程序执行过程中的问题,但它们之间存在一些重要的区别。

  1. 异常(Exception)

    • 异常表示程序在执行期间可能遇到的意外情况。它们通常是由程序本身的逻辑错误或外部环境的异常情况引起的,比如文件未找到、数组越界、空指针引用等。
    • 异常是可以被程序处理的,Java提供了异常处理机制(try-catch-finally)来捕获、处理和传播异常,以保证程序在遇到异常情况时能够恰当地做出响应,从而保证程序的稳定性和可靠性。
  2. 错误(Error)

    • 错误表示程序运行时的严重问题,通常是由于系统资源耗尽、虚拟机内部错误等导致的。错误通常是不可恢复的,例如OutOfMemoryErrorStackOverflowError等。
    • 错误通常是由系统或虚拟机引起的,程序本身很少有能力处理错误。当出现错误时,程序一般会终止执行,并且通常需要由系统管理员或开发者介入解决。

总的来说,异常是程序中可预见的、可以通过异常处理机制来处理的问题,而错误通常是不可预见的、由系统或虚拟机引起的严重问题,很少有能力处理。在Java中,异常和错误都是Throwable类的子类,但它们用于不同的场景,需要有针对性地处理和处理。

二、异常的作用

异常在编程中有多种意义和作用,主要包括以下几个方面:

  1. 提供了一种标准的错误处理机制:异常提供了一种结构化的方式来处理程序中可能发生的错误情况。通过异常,程序可以更清晰地区分正常情况和异常情况,并且能够在发生异常时采取适当的行动。

  2. 提高了代码的可读性和可维护性:异常使得代码结构更清晰,异常处理代码可以将错误处理逻辑从主要的业务逻辑中分离出来,使得代码更易读、易理解,并且更容易维护。

  3. 提供了一种机制来传递错误信息:异常提供了一种标准的方式来传递错误信息,通过异常对象可以包含详细的错误信息,包括错误类型、原因、位置等,这有助于程序员诊断和修复问题。

  4. 强制程序员处理异常情况:对于受检异常,Java 强制要求程序员在代码中明确处理可能抛出的异常,这有助于程序员编写更健壮的代码,提高程序的可靠性。

  5. 支持了程序中的异常流程控制:异常提供了一种非常灵活的流程控制机制,可以在发生异常时跳转到指定的异常处理代码块,并且可以通过异常传播机制在调用栈中传递异常对象。

三、异常分类

  • Throwable 类

    • Throwable 是 Java 中所有异常和错误的超类。
    • Throwable 类有两个直接子类:Error 和 Exception。
  • Error 类

    • Error 类表示 Java 运行时系统的内部错误或者虚拟机无法解决的严重问题。
    • Error 类的子类通常表示系统级别的问题,通常无法通过程序来恢复。
    • 一些常见的 Error 子类包括:OutOfMemoryError、StackOverflowError、NoClassDefFoundError 等。
  • Exception 类

    • Exception 类表示程序运行过程中可能遇到的异常情况,通常可以通过程序来处理。
    • Exception 类的子类通常表示程序中的错误或异常情况,可以通过合适的处理逻辑来处理或者恢复。
    • Exception 类的子类又可以分为两大类:受检异常(Checked Exception)和非受检异常(Unchecked Exception)。
  • 受检异常(Checked Exception)编译时异常

    • 受检异常是指需要在方法声明中使用 throws 关键字或者在调用处使用 try-catch 块进行处理的异常。
    • 受检异常通常表示程序的可预见的异常情况,例如文件未找到、数据库连接失败等。
    • 一些常见的受检异常包括:IOException、SQLException、ClassNotFoundException 等。
  • 非受检异常(Unchecked Exception)运行时异常

    • 非受检异常是指不需要在方法声明中使用 throws 关键字或者在调用处使用 try-catch 块进行处理的异常。
    • 非受检异常通常表示程序中的编程错误或者逻辑错误,例如空指针引用、数组越界、类型转换错误等。
    • 一些常见的非受检异常包括:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException 等。

四、异常的处理机制

  • 当谈到Java异常处理机制时,可以分为以下三个主要部分:
  • 抛出异常
    • 在程序执行过程中,当遇到异常情况时,可以使用 throw 关键字抛出异常。throw 关键字后跟一个异常对象,该对象是一个异常类的实例。通过抛出异常,可以在程序中指示发生了异常情况,从而中断当前的执行流程。
      throw new SomeException("An error occurred");
      
  • 捕获异常
    • 在程序中,可以使用 try-catch 块来捕获并处理可能抛出的异常。try 块中包含可能引发异常的代码,而 catch 块用于捕获和处理异常。在 catch 块中可以针对不同类型的异常进行相应的处理逻辑。
      try {
          // 可能抛出异常的代码
      } catch (SomeException e) {
          // 处理异常的代码
      } finally {
          // 无论是否发生异常,都会执行的代码
      }
      

  • throws 子句
    • 在方法的声明中,使用 throws 子句来声明方法可能抛出的异常类型
      public void someMethod() throws SomeException {
          // 方法可能抛出 SomeException
      }
      

五、异常的传播机制: 

一个方法抛出异常时,如果该异常在当前方法中未被捕获,那么它将会传播到调用堆栈的更高层次。具体来说,Java的异常传播是通过堆栈解开(unwinding the stack)的方式进行的。当一个方法调用另一个方法时,调用栈会将调用者的信息压入堆栈,形成一个调用链。

当一个方法中的异常没有被捕获时,Java运行时系统会查找当前方法的调用者。如果调用者也没有捕获该异常,异常会继续传播到调用者的调用者,以此类推,直到找到一个能够处理该异常的地方或者到达调用堆栈的顶部。

在调用堆栈的更高层次,您可以使用try-catch语句来捕获并处理异常,或者将异常向上抛出(不捕获异常,而是将其传递给更高层次的调用者)。

public class Example {
    public void methodA() {
        try {
            methodB();
        } catch (SomeException e) {
            // 处理异常
            System.out.println("Caught exception in methodA: " + e.getMessage());
        }
    }
    
    public void methodB() throws SomeException {
        // 模拟抛出异常
        throw new SomeException("Exception in methodB");
    }
}

在上面的例子中,如果methodB()抛出了SomeException,它将会传播到调用methodB()的地方。由于methodA()包含一个try-catch块,它会捕获SomeException异常,并进行处理。如果methodA()没有捕获异常,那么异常将继续传播到调用methodA()的地方,以此类推,直到找到一个能够处理该异常的地方,或者到达调用堆栈的顶部,导致程序终止。

六、自定义异常

在 Java 中,你可以通过创建一个类来定义自己的异常,通常继承自 ExceptionRuntimeException,具体取决于你的自定义异常是受检异常还是非受检异常。以下是一个简单的例子:

// 自定义一个受检异常
class MyCheckedException extends Exception {
    // 构造方法,用于传递异常消息
    public MyCheckedException(String message) {
        super(message);
    }
}

// 自定义一个非受检异常
class MyUncheckedException extends RuntimeException {
    // 构造方法,用于传递异常消息
    public MyUncheckedException(String message) {
        super(message);
    }
}

在上面的例子中,我们定义了两个自定义异常类 MyCheckedExceptionMyUncheckedException,分别继承自 ExceptionRuntimeException。这两个类都有一个带有字符串参数的构造方法,用于传递异常消息。接下来,你可以在代码中使用你定义的自定义异常,例如:

public class Main {
    // 抛出自定义受检异常
    public static void throwCheckedException() throws MyCheckedException {
        throw new MyCheckedException("This is a checked exception");
    }

    // 抛出自定义非受检异常
    public static void throwUncheckedException() {
        throw new MyUncheckedException("This is an unchecked exception");
    }

    public static void main(String[] args) {
        try {
            throwCheckedException();
        } catch (MyCheckedException e) {
            System.out.println("Caught checked exception: " + e.getMessage());
        }

        throwUncheckedException();
    }
}

 在 main 方法中,我们分别调用了抛出自定义受检异常和非受检异常的方法,并进行了相应的异常处理。通过自定义异常,你可以更好地管理你的异常情况,并且可以在异常消息中提供更多的信息,便于调试和处理异常情况。

七、受查异常与非受查异常的根本区别

受查异常(Checked Exception)和非受查异常(Unchecked Exception)是 Java 中异常的两个主要类型,它们的根本区别在于编译器对它们的处理方式不同。

  1. 受查异常(Checked Exception)

    • 受查异常是指在编译期间必须进行处理的异常,即在代码中必须显式地处理或者声明可能抛出的受查异常。
    • 如果一个方法可能抛出受查异常,它要么在方法内部使用 try-catch 块捕获并处理异常,要么在方法声明中使用 throws 关键字将异常继续传播给调用者。
  2. 非受查异常(Unchecked Exception)

    • 非受查异常是指在编译期间不需要进行处理的异常,即在代码中可以不处理或者声明可能抛出的非受查异常。
    • 对于非受查异常,编译器不会强制要求在方法声明中使用 throws 关键字或者在调用处使用 try-catch 块进行处理。

也就是说,如果我们所以的异常都由JVM来处理,那么受查异常与非受查异常的区别就是,要不要用throws告诉目前的调用堆栈来处理异常,而在实际开发中,我们也可以用两者异常的重要程度不同来判定我们自己的异常要继承那个类。

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

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

相关文章

Memcached介绍和详解

Memcached介绍 Memcached是一个高性能的分布式内存对象缓存系统,它通过在内存中缓存数据来减少数据库负载,加快动态Web应用程序的响应速度。 以下是Memcached的一些关键特点和作用: 分布式缓存:Memcached是分布式的,不…

Android高级工程师面试实战,三幅图给你弄懂EventBus核心原理

阿里技术一面-35min 自我介绍 Android 有没有遇到OOM问题(有遇到内存泄漏问题)Handler机制ThreadLocalActivity启动到加载View过程View绘制过程LinearLayout (wrap_content) & TextView (match_parent) 最终结果???OKHttp(1. 为什么选择它? 2. 性能了解不…

阿里云服务器几核几G怎么选择?带宽多少合适?

阿里云服务器配置怎么选择?CPU内存、公网带宽和系统盘怎么选择?个人开发者或中小企业选择轻量应用服务器、ECS经济型e实例,企业用户选择ECS通用算力型u1云服务器、ECS计算型c7、通用型g7云服务器,阿里云服务器网aliyunfuwuqi.com整…

Java 学习和实践笔记(27):Object类的基本特性、toString方法以及IDEA的部分快捷键介绍

Object类基本特性: 1.Object类是所有类的父类,所有的Java对象都拥有Object类的属性和方法(注意拥有并不等于可以直接使用) 2.如果在类的声明中未使用extends,则默认继承Object类。 toString方法是Object类里定义的一个…

Word中的文档网格线与行距问题

在使用Word编辑文档时,经常会发生以下动图展示的这种情况: 上面的动图里,将文字大小放大到某个字号时,单倍行距的间距突然增加很多。造成这种情况的原因是文档中定义了网格线,并且设置了对齐到网格线。如果取消文档中…

[清爽快捷] Ubuntu上多个版本的cuda切换

做到真正的一行代码搞定,只需要修改对应软链接,就可以轻松实现快捷切换cuda 查看已安装的cuda版本有哪些 一般如果我们都是使用默认位置安装cuda的话,那么其安装路径都是/usr/local。如果要查看该目录下已经安装有哪些版本的cuda&#xff0c…

Git分布式管理-头歌实验本地版本库

一、本地版本库创建 任务描述 本地Git操作三部曲是“修改-添加-提交”,即先要在本地仓库进行添加、删除或编辑等修改,然后将本地所做的修改添加至暂存区。添加至暂存区的这些本地修改,并未提交到本地仓库,需要执行提交命令才能将暂…

SPSS26安装后无法启动,提示:应用程序的并行配置不正确

以下的解决方法供参考: 1、安装jdk并配置 2、 找到安装目录\Statistics\26\VC9下的vcredist_x64.exe,打开安装并选择“repair”,安装完成后重启,一般可以成功。 3、若还不行,安装较新的C运行库,再试试。 …

勒索病毒攻击新玩法,先盗数据再勒索

2019年是勒索病毒团伙针对企业进行勒索攻击爆发的一年,全球多个国家的政府组织机构、企事业单位都成为了勒索病毒团伙攻击的目标,勒索病毒也成为了网络安全最大的网络安全威胁,新的勒索病毒不断涌现,旧的勒索病毒不断变种&#xf…

1.1 深度学习和神经网络

首先要说的是:深度学习的内容,真的不难。你要坚持下去。 神经网络 这就是一个神经网络。里面的白色圆圈就是神经元。神经元是其中最小的单位。 神经网络 单层神经网络: 感知机 (双层神经网络) 全连接层: …

DHCP自动获取IP地址实验(华为)

思科设备参考&#xff1a;DHCP自动获取IP地址实验&#xff08;思科&#xff09; 一&#xff0c;实验目的 路由器搭载DHCP&#xff0c;让PC通过DHCP自动获取IP地址 二&#xff0c;不划分vlan--全局地址池 实验拓扑 配置命令 Router <Huawei>system-view [Huawei]ip po…

十三、类的继承、访问级别

类的继承与访问控制 类的继承 使用sealed修饰的类&#xff0c;是私有类&#xff0c;不能作为基类使用C#中一个类&#xff0c;只能有一个父类&#xff0c;但是可以实现多个接口子类的访问级别不能超过父类的访问级别 using System; using System.Collections.Generic; using S…

HDFS简介与部署以及故障排错(超简单)

文章目录 一、HDFS介绍1、简介2、结构模型3、文件写入过程4、文件读取过程5、文件块的存放6、存储空间管理机制6.1 文件删除和恢复删除6.2 复制因子配置6.3 文件命名空间6.4 数据复制机制 二、环境搭建&#xff08;单机版&#xff09;1、修改主机名2、配置ssh免密登录3、Hadoop…

HTML表单标签,web前端开发新技术

1、ant-design的使用总结及常用组件和他们的基本用法? ant-design为React&#xff0c;Angular和Vue都提供了组件&#xff0c;同时为PC和移动端提供了常用的基础组件。ant-design提供的demo非常的丰富并且样式能够基本的覆盖开发需求。antd的Demo因为是多人编写的&#xff0c;…

(vue)适合后台管理系统开发的前端框架

(vue)适合后台管理系统开发的前端框架 1、D2admin 开源地址&#xff1a;https://github.com/d2-projects/d2-admin 文档地址&#xff1a;https://d2.pub/zh/doc/d2-admin/ 效果预览&#xff1a;https://d2.pub/d2-admin/preview/#/index 开源协议&#xff1a;MIT 2、vue-el…

自动化测试基础——Pytest框架之YAML详解以及Parametrize数据驱动

文章目录 一、YAML详解1.YAML作用2.YAML语法结构3.YAML数据类型3.1.对象3.2.数组3.3.标量 4.YAML的引用5.YAML类型转换 二、YAML的读写与清空1.YAML的读2.YAML的写3.YAML的清空 三、pytest的parametrize简单数据驱动四、pytest的parametrize结合yaml实现数据驱动五、解决pytest…

LeetCode Python - 36.有效的数独

目录 题目答案运行结果 题目 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08…

CSS 选择器的常见用法

CSS选择器的主要功能就是选中⻚⾯指定的标签元素.选中了元素,才可以设置元素的属性. CSS选择器主要分以下⼏种: 1. 标签选择器 2. class选择器 3. id选择器 4. 复合选择器 5. 通配符选择器 <body><div class"font32"> 我是一个div,class为front32</…

D*算法超详解 (D星算法 / Dynamic A*算法/ Dstar算法)(死循环解决--跟其他资料不一样奥)

所需先验知识&#xff08;没有先验知识可能会有大碍&#xff0c;了解的话会对D*的理解有帮助&#xff09;&#xff1a;A*算法/ Dijkstra算法 何为D*算法 Dijkstra算法是无启发的寻找图中两节点的最短连接路径的算法&#xff0c;A*算法则是在Dijkstra算法的基础上加入了启发函数…

docker-compose Install rustdesk

RustDesk RustDesk 是一款开源的远程支持和远程桌面工具,它旨在为用户提供便捷的远程协助和远程访问功能。 默认情况下,hbbs 监听21115(tcp), 21116(tcp/udp), 21118(tcp),hbbr 监听21117(tcp), 21119(tcp)。务必在防火墙开启这几个端口, 请注意21116同时要开启TCP和UDP。…