异常的顶级理解

news2024/9/23 11:18:21

目录

1.异常的概念与体系结构

 1.1异常的体系结构

1.2异常的举例

1.3错误的举例

 2.异常的分类

2.1编译时异常

 2.2运行时异常

3.异常的处理

3.1异常的抛出throw

3.2try-catch捕获并处理

3.3finally

3.4 异常声明throws

4.自定义异常类


1.异常的概念与体系结构

 1.1异常的体系结构

异常种类繁多,为了对不同异常或者错误进行很好的分类管理, Java 内部维护了一个异常的体系结构:

  从上图中可以看到:

1. Throwable 是异常体系的顶层类,其派生出两个重要的子类 , Error Exception
2. Error 指的是 Java 虚拟机无法解决的严重问题,比如: JVM 的内部错误、资源耗尽等 ,典型代表: StackOverflflowError OutOfMemoryError ,一旦发生回力乏术。
3. Exception 异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说 的异常就是Exception

 

1.2异常的举例

Java 中,将程序执行过程中发生的不正常行为称为异常
比如:
(1)算术异常
 public static void main(String[] args) {
        System.out.println(10/0);
    }

运行结果及分析:

补充:

 

 (2)数组越界异常

public static void main(String[] args) {
       int[] arr = {1, 2, 3,4,5};
       System.out.println(arr[10]);

    }
// 执行结果
Exception in thread "main" java . lang . ArrayIndexOutOfBoundsException : 100
(3)空指针异常
public static void main(String[] args) {
        int[] arr = null;
        System.out.println(arr.length);
    }
// 执行结果
Exception in thread "main" java . lang . NullPointerException

1.3错误的举例

StackOverflflowError

public class Text2 {
    public static void fun(){
        fun();
    }

    public static void main(String[] args) {
        fun();
    }
}

执行结果:


 2.异常的分类

异常可能在编译时发生,也可能在程序运行时发生,根据发生的时机不同,可以将异常分为:

2.1编译时异常

在程序编译期间发生的异常,称为编译时异常,也称为受检查异常 (Checked Exception)
举个经典的例子:

理解: 

正确完整代码:

public class Text3 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person(18, "WH");
        Person p2= (Person) p1.clone();
    }
}
public class Person {
    int age;
    String nume;

    public Person(int age, String nume) {
        this.age = age;
        this.nume = nume;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

 2.2运行时异常

在程序执行期间发生的异常,称为运行时异常,也称为非受检查异常 (Unchecked Exception)
RunTimeException 以及其子类对应的异常,都称为运行时异常
比如:
NullPointerException 、 ArrayIndexOutOfBoundsException、 ArithmeticException
在1.2异常的举例中展示了相关代码
注意:编译时出现的语法性错误,不能称之为异常。
例如将 System.out.println 拼写错了 , 写成了 system.out.println. 此时编译过程中就会出错 , 这是 " 编译期 " 出错。
而运行时指的是程序已经编译通过得到 class 文件了 , 再由 JVM 执行过程中出现的错误 .

 


3.异常的处理

在Java中,异常处理主要的5个关键字:try、catch、final、throw、throws。

异常的捕获,也就是异常的具体处理方式,主要有两种:异常声明throws 以及 try-catch捕获处理。

3.1异常的抛出throw

在编写程序时,如果程序中出现错误,此时就需要将错误的信息告知给调用者
在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者
语法:
throw new XXXException ( " 异常产生的原因 " )
主动抛出指定异常

运行结果:

Exception in thread "main" java.lang.NullPointerException: hahaha

注意事项
(1) throw 必须写在方法体内部
(2)抛出的对象必须是 Exception 或者 Exception 的子类对象
(3) 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处                 理, 直接交给JVM来处理
(4)如果抛出的是编译时异常,用户必须处理,否则无法通过编译
(5)异常一旦抛出,其后的代码就不会执行

对于(3)(5)举例:

3.2try-catch捕获并处理

语法形式:

如果真正要对异常进行 处理,就需要try-catch
注意事项
(1) try块内抛出异常位置之后的代码将不会被执行
public static void main(String[] args) {
        try{
            System.out.println(10/0);
            System.out.println(100);
        }catch (ArithmeticException e){
            e.printStackTrace();
        }
    }

运行结果:

java.lang.ArithmeticException: / by zero

(2)如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到 JVM收到后中断程序----异常是按照类型来捕获的

public static void main(String[] args) {
        try {
            System.out.println(10/0);
        } catch (NullPointerException e) {
            System.out.println(10);
        }
    }

运行结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero

没有打印10,而是报java.lang.ArithmeticException: / by zero,
因为:异常没有被成功捕获,也就不会被处理继续往外抛,直到 JVM收到后中断程序
(3)try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获----即多种异常,多次捕获

 

(4)如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则语法错误

(5)可以通过一个catch捕获所有的异常,即多个异常,一次捕获(不推荐)

Exception 类是所有异常类的父类. 因此可以用这个类型表示捕捉所有异常

3.3finally

在写程序时, 有些特定的代码,不论程序是否发生异常,都需要执行,比如程序中打开的资源 :网络连接、数据库 连接、IO 流等, 在程序正常或者异常退出时,必须要对资源进进行回收 。另外,因为 异常会引发程序的跳转,可能 导致有些语句执行不到 finally 就是用来解决这个问题的。
小结: finally 中的代码一定会执行的,一般在 finally 中进行一些资源清理的扫尾工作
注意:
finally 执行的时机是在方法返回之前 (try 或者 catch 中如果有 return 会在这个 return 之前执行 fifinally). 但是如果 finally 中也存在 return 语句 , 那么就会执行 fifinally 中的 return, 从而不会执行到 try 中原有的 return.
一般我们不建议在 finally 中写 return ( 被编译器当做一个警告 )

 

3.4 异常声明throws

处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助 throws 将异常抛 给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常

 

语法格式:

修饰符 返回值类型 方法名 ( 参数列表 ) throws 异常类型 1 ,异常类型 2 ...{
}

  注意:

如果方法是main方法调用者仍然可以不处理异常,借助throws将异常抛 给JVM来处理。

注意事项
1. throws 必须跟在方法的参数列表之后
2. 声明的异常必须是 Exception 或者 Exception 的子类
3. 方法内部如果抛出了多个异常, throws 之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型 具有父子关系,直接声明父类即可。
4.我们在使用throws时,要明确声明的异常是编译时异常还是运行时异常。

比如:

(1)

(2) 

 

如果是 运行时异常调用者不处理异常也没关系,JVM会处理。

如果是编译时异常一定要处理异常

处理方式:(1)try-catch捕获并处理

                  (2)借助throws将异常抛 给JVM来处理。



4.自定义异常类

Java 中虽然已经内置了丰富的异常类 , 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我 们实际情况的异常结构.
如何自定义异常类?
例题:

定义Course类,Course包含private String cno,private String cname,private int credit,Course包括方法:public Course(),public Course。Define CreditException类扩展(继承) 在RunTimeException中,CreditException包含以下方法:public CreditException()、public CreditException(String Message)。

如果课程的学分低于0.5或高于6,则课程的构建方法将抛出CreditException,消息为“学分应在0.5和6之间!”。

定义公共类TestCourse,创建一个Course对象,并使用try/catch块来处理CreditException。

代码:
import java.util.Scanner;

public class LogIn {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入cno");
        String cno=scanner.next();
        System.out.println("请输入课程名字");
        String cname=scanner.next();
        System.out.println("请输入学分");
        double credit=scanner.nextDouble();
        Course course=new Course(cno,cname,credit);
        try {
            if(!(course.getCredit()>=0.5&&course.getCredit()<=6)){
                throw new CreditException("课程的学分应在0.5到6之间");
            }else{
                System.out.println("输入成功学分为:"+course.getCredit());
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
class Course{
    private String cno;
    private String cname;
    private double credit;
    public Course(String cno, String cname, double credit) {
        this.cno = cno;
        this.cname = cname;
        this.credit = credit;
    }
    public Course() {
    }
    public String getCno() {
        return cno;
    }
    public void setCno(String cno) {
        this.cno = cno;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public double getCredit() {
        return credit;
    }
    public void setCredit(double credit) {
        this.credit = credit;
    }

}
class CreditException extends RuntimeException{
    public CreditException(String message){
        super(message);
    }
}

注意事项

  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常

以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

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

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

相关文章

BMS电池管理系统——什么是BMS(一)

BMS电池管理系统 文章目录 BMS电池管理系统前言一、BMS是什么&#xff1f;二、BMS的主要功能模块1.采样及测量功能2.状态估计及预测功能3.控制及管理功能4.通讯和诊断功能 总结 前言 作为一名电气专业的学生&#xff0c;大学里学了很多嵌入式相关的知识&#xff0c;首先要明确…

便捷高效的一键发布成绩

今天我要给大家推荐一个非常实用的教育工具——易查分。作为一名教育工作者&#xff0c;我深知每次发布成绩都是一项繁琐而重要的任务。然而&#xff0c;有了易查分&#xff0c;这一切都变得轻松高效起来。让我来告诉各位老师&#xff0c;易查分是如何实现一键发布成绩的&#…

Xilinx IDDR与ODDR原语的使用

文章目录 ODDR原语1. OPPOSITE_EDGE 模式2. SAME_EDGE 模式 ODDR原语 例化模板&#xff1a; ODDR #(.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT(1b0), // Initial value of Q: 1b0 or 1b1.SRTYPE("SYNC…

Scrapy的基本介绍、安装及工作流程

一.Scrapy介绍 Scrapy是什么&#xff1f; Scrapy 是用 Python 实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架(异步爬虫框架) 通常我们可以很简单的通过 Scrapy 框架实现一个爬虫&#xff0c;抓取指定网站的内容或图片。 Scrapy使用了Twisted异步网络框架&…

【LeetCode题目详解】第九章 动态规划 part05 1049. 最后一块石头的重量 II 494. 目标和 474.一和零(day43补)

本文章代码以c为例&#xff01; 一、力扣第1049题&#xff1a;最后一块石头的重量 II 题目&#xff1a; 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎…

C++学习记录——삼십삽 STL空间配置器

文章目录 1、概念2、使用3、容器上的体现 1、概念 我们先看malloc&#xff0c;malloc是创建在堆上的&#xff0c;虽然malloc可以申请内存&#xff0c;但也有限制&#xff0c;windows下用VirtualAlloc可以直接向堆申请内存&#xff0c;Linux中则是brk&#xff0c;不过这两个效率…

HCIA自学笔记01-传输介质

通信网络除了包含通信设备本身之外&#xff0c;还包含连接这些设备的传输介质&#xff0c;如同轴电缆、双绞线和光纤等。不同的传输介质具有不同的特性&#xff0c;这些特性直接影响到通信的诸多方面&#xff0c;如线路编码方式、传输速度和传输距离等。 简单网络&#xff1a;…

✔ ★算法基础笔记(Acwing)(一)—— 基础算法(20道题)【java版本】

基础算法 一、快速排序1. 快速排序例题2. 第k个数( 快速选择 ) ✔ ✔1.31★快排二刷总结( 4点 ) 二、归并排序1. 归并排序模板题 ✔ ✔1.31★二刷总结 ★2. 逆序对的数量 ✔ ✔1.31★二刷总结 三、二分1. 数的范围 ✔1.31★二刷总结(mid > x 则是 输出最左边一个)第一个大于…

【操作系统】聊聊Linux内存工作机制

内存主要是用来存储系统和应用程序的指令、数据、缓存等 内存映射 内存是需要安全机制保护的&#xff0c;所以只有内核才可以直接访问物理内存。进程如果要访问内存需要通过独立的虚拟地址空间。 虚拟地址空间其实包含两部分。一部分是内核空间&#xff0c;另一部分就是用户…

搭建RabbitMQ消息服务,整合SpringBoot实现收发消息

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;3年JAVA全栈开发经验&#xff0c;专注JAVA技术、系统定制、远程指导&#xff0c;致力于企业数字化转型&#xff0c;CSDN博客专家&#xff0c;蓝桥云课认证讲师。 目录 一、前言1.1 什么是消息队列1.2 RabbitMQ 是什么1.…

【AI】机器学习——线性模型(线性回归)

线性模型既能体现出重要的基本思想&#xff0c;又能构造出功能更加强大的非线性模型 文章目录 3.1 线性模型3.1.1 数据3.1.2 目标/应用 3.2 线性回归3.2.1 回归模型历史3.2.2 回归分析研究内容回归分析步骤 3.2.3 回归分析分类3.2.4 回归模型3.2.5 损失函数梯度下降法一元回归模…

【数据仓库基础(二)】数据仓库架构

文章目录 一. 基本架构二. 主要数据仓库架构1. 数据集市架构1.1. 独立数据集市1.2. 从属数据集市1.3. Inmon企业信息工厂架构 2. Kimball数据仓库架构3. 混合型数据仓库架构 三. 操作数据存储&#xff08;ODS&#xff09; 一. 基本架构 架构是指系统的一个或多个结构。结构中包…

stride与padding对输出尺寸的计算

公式&#xff1a; 练习&#xff1a; 图1&#xff1a; input4&#xff0c;filter3&#xff0c;padding0&#xff0c;stride1 output2 图2&#xff1a; input5&#xff0c;filter3&#xff0c;padding0&#xff0c;stride2 output2 图3&#xff1a; input6&#xff0c;filter3&am…

设计模式之观察者模式、访问者模式与模板方法模式

目录 观察者模式 简介 优缺点 结构 实现 运用场景 访问者模式 简介 优缺点 结构 实现 运用场景 模板方法模式 简介 优缺点 结构 实现 运用场景 观察者模式 简介 又叫发布-订阅模式&#xff0c;定义对象间一种一对多的依赖关系&#xff0c;使得每当一个对象改…

Android 应用程序通过MediaPipe 图片识别

MediaPipe 中使用目标检测模型可以实现实时检测图像或视频中的物体&#xff0c;并标记出物体的位置和类别。MediaPipe 中的目标检测模型基于机器学习算法&#xff0c;经过训练以识别特定的物体类别&#xff1b; 以下是在 Android 应用程序中集成 MediaPipe Object Detection 的…

SpringMVC应用

文章目录 一、常用注解二、参数传递2.1 基础类型String2.2 复杂类型2.3 RequestParam2.4.路径传参 PathVariable2.4 Json数据传参 RequestBody2.5 RequestHeader 三、方法返回值3.1 void3.2 Stringmodel3.3 ModelAndView 一、常用注解 SpringMVC是一个基于Java的Web框架&#…

Nacos启动连接mysql报错

问题 Nacos启动后&#xff0c;访问http://localhost:8848/nacos/index.html一直访问不了&#xff0c;查看nacos安装目录下的logs/config-fatal.log日志文件发现连接mysql报错&#xff0c;但是通过客户端连接工具测试mysql连接正常&#xff1b;核心报错如下&#xff1a; Cause…

【线程池】面试被问到线程池参数如何配置时该如何回答

前言 没有基于业务场景&#xff0c;直接抛出这个问题&#xff0c;等同于耍流氓。 八股文告诉我们CPU密集型就核心数1&#xff0c;IO密集型就核心数*2&#xff0c;那么真实业务中该怎么去配置呢。 方法论还是有的 1.需要分析线程池执行的任务的特性&#xff1a; CPU 密集型还是 …

【操作】安防监控/视频汇聚/视频云存储EasyCVR平台AI智能分析网关V3接入教程2.0

TSINGSEE的边缘计算硬件智能分析网关V3内置多种AI算法模型&#xff0c;包括人脸、人体、车辆、车牌、行为分析、烟火、入侵、聚集、安全帽、反光衣等等&#xff0c;可应用在安全生产、通用园区、智慧食安、智慧城管、智慧煤矿等场景中。将网关硬件结合TSINGSEE青犀的视频汇聚/安…

数据结构-01 数据结构基本概念,算法时间复杂度,空间复杂度

0 数据结构概述 四门课的关系 1 绪论 数据对象、数据元素、数据项关系 1.1 数据结构的基本概念 1.2 算法和算法评价 小练习 空间复杂度中的递归调用 n只是传入 n也是数组&#xff0c;计算存储数组flag的空间大小