关于java异常的整理

文章目录

  • 一、异常分类
  • 二、throw、throws、try-catch-finally
  • 三、CglibAopProxy中对异常的处理
  • 4、关于UndeclaredThrowableException

一、异常分类

java异常层级结构

  • Throwable:所有异常的根接口
    • Error:严重错误,程序无法处理和恢复
      • 例如VirtualMachineError,OOMError等
    • Exception:异常,程序可以捕获并可能恢复
      • RuntimeException: 运行时异常,无需强制捕获
        • NullPointerException
        • ClassCastException
        • ArithmeticException
        • IllegalArgumentException
      • IOException: IO操作异常
        • FileNotFoundException
        • SocketException
      • SQLException: SQL数据库访问异常
      • TimeoutException: 超时异常
      • ParseException: 解析错误异常
      • OtherException: 其他领域特定的异常
        • HttpException
        • ASFException
      • 自定义Exception:用户自定义的业务异常

从另一个角度看java异常分为Checked Exception和Unchecked Exception

  • Checked Exception: 需要捕获或者声明抛出的异常,如果没有处理则不能编译通过。主要包括Exception及其子类,不包括RuntimeException。例如IOException、SQLException等。
  • Unchecked Exception: 不需要强制捕获的异常,可以不处理。主要包括RuntimeException及其子类。例如NullPointerException、ClassCastException等

Checked Exception举例:

public class Test{
    public static void main(String[] args) throws IllegalAccessException {
        int a = new Random().nextInt(10);
        System.out.println(a);
        if(a % 2 == 1){
            throw new IllegalAccessException("This is an checked exception.");
        }
    }
}

这里如果不声明(throws)或捕获(try-catch)异常编译会报错

在这里插入图片描述
加上throws IllegalAccessException编译通过,运行结果如下
在这里插入图片描述

Unchecked Exception举例:

public class Test {
    public static void main(String[] args){
        int a = new Random().nextInt(10);
        System.out.println(a);
        if(a % 2 == 1){
            throw new IllegalArgumentException("This is an unchecked exception.");
        }
    }
}

这里没有throws或try-catch编译通过
在这里插入图片描述
运行结果如下
在这里插入图片描述
ps::注意上面例子上两种异常(IllegalAccessException和IllegalArgumentException),不要看错了

二、throw、throws、try-catch-finally

  • throw: 用于抛出一个异常对象,通常在方法体内使用。

例如:

throw new IOException("文件读取错误");
  • throws: 声明一个方法可能抛出的异常类型,出现在方法签名中。

例如:

public void readFile(String file) throws IOException {
  // 方法实现
}
  • try-catch-finally: 用于捕获异常,try代码块表示需要捕获异常的代码,catch表示捕获到异常后的处理逻辑,finally表示需要额外处理的逻辑
    finally中的内容是一定会执行的,无论有没有捕获异常。常用于关闭IO流等做一些收尾操作。

例如:

try {
  readFile(file); 
} catch (IOException e) {
  // 处理IO异常
} finally {
  // 额外逻辑
}

三、CglibAopProxy中对异常的处理

在CglibAopProxy中有一个内部类CglibMethodInvocation,而CglibMethodInvocation中的proceed()方法对捕获的异常做了一个逻辑处理

        @Nullable
        public Object proceed() throws Throwable {
            try {
                return super.proceed();
            } catch (RuntimeException var2) {
            	// RuntimeException或其子类直接抛出 ---- 1
                throw var2;
            } catch (Exception var3) {
            	// 非RunTimeException需根据Cglib代理的方法抛出的异常判断 ---- 2
            	// 是代理方法抛出的异常或该异常的子类则 ---- 3
            	// 若不是则抛出UndeclaredThrowableException异常 ---- 4
                if (!ReflectionUtils.declaresException(this.getMethod(), var3.getClass()) && !KotlinDetector.isKotlinType(this.getMethod().getDeclaringClass())) {
                    throw new UndeclaredThrowableException(var3);
                } else {
                    throw var3;
                }
            }
        }

上述代码2、3、4实现主要由if语句条件中ReflectionUtils.declaresException()方法实现
方法参数:
Method method:代理的方法
Class<?> exceptionType:抛出的异常(不是代理方法抛出的),这里是aop中抛出的IllegalAccessException

    public static boolean declaresException(Method method, Class<?> exceptionType) {
        Assert.notNull(method, "Method must not be null");
        // 获取代理方法中抛出的异常类型
        Class<?>[] declaredExceptions = method.getExceptionTypes();
        Class[] var3 = declaredExceptions;
        int var4 = declaredExceptions.length;
		
		// 判断捕获的异常是否是代理方法抛出的异常或该异常子类
        for(int var5 = 0; var5 < var4; ++var5) {
            Class<?> declaredException = var3[var5];
            if (declaredException.isAssignableFrom(exceptionType)) {
                return true;
            }
        }

        return false;
    }

举例说明:
这里自定义注解+aop切面增强某个controller方法时抛出了IllegalAccessException异常
在这里插入图片描述
controller中并未throws任何异常
在这里插入图片描述
运行结果
在这里插入图片描述
返回给前端的结果也是这个,并没有返回我们写的IllegalAccessException
打断点调试
先走到CglibAopProxy这
因为IllegalAccessException不是RuntimeException的子类,所以走到了if条件语句这
在这里插入图片描述
进入到ReflectionUtils.declaresException()方法
在这里插入图片描述
查看控制台debug的内容可知他从method中获取的异常类型
在这里插入图片描述
可见是没有获取到任何异常的,因为上面controller中并未手动抛出任何异常
所以最后ReflectionUtils.declaresException(this.getMethod(), var3.getClass())返回的结果是false
抛出UndeclaredThrowableException异常
看名字能知道这个异常的意思是未声明的异常

4、关于UndeclaredThrowableException

一文搞懂 UndeclaredThrowableException

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

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

相关文章

【图像去噪】基于原始对偶算法优化的TV-L1模型进行图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

8.5作业

要求实现AB进程对话 a.A进程先发送一句话给B进程&#xff0c;B进程接收后打印 b.B进程再回复一句话给A进程&#xff0c;A进程接收后打印 c.重复1.2步骤&#xff0c;当收到quit后&#xff0c;要结束AB进程 A进程 #include<stdio.h> #include<string.h> #include&…

【新版系统架构补充】-七层模型

网络功能和分类 计算网络的功能 &#xff1a;数据通信、资源共享、管理集中化、实现分布式处理、负载均衡 网络性能指标&#xff1a;速率、带宽&#xff08;频带宽度或传送线路速率&#xff09;、吞吐量、时延、往返时间、利用率 网络非性能指标&#xff1a;费用、质量、标准化…

【Rust】Rust学习

文档&#xff1a;Rust 程序设计语言 - Rust 程序设计语言 简体中文版 (bootcss.com) 墙裂推荐这个文档 第一章入门 入门指南 - Rust 程序设计语言 简体中文版 第二章猜猜看游戏 猜猜看游戏教程 - Rust 程序设计语言 简体中文版 (bootcss.com) // 导入库 use std::io; use s…

2023.08.01 驱动开发day8

驱动层 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/of_gpio.h>#…

NVM保姆级安装配置

nvm安装配置 1、NVM简介2、NVM安装三、NVM使用四、NVM常用命令 1、NVM简介 在项目开发过程中&#xff0c;使用到vue框架技术&#xff0c;需要安装node下载项目依赖&#xff0c;但经常会遇到node版本不匹配而导致无法正常下载&#xff0c;重新安装node却又很麻烦。为解决以上问…

Docker 网络模型使用详解 (1)Dockers网络基础

目录 环境准备 Dockers 网络基础 1.端口映射 查看随机映射端口范围 -p可以指定映射到本地端口 映射指定地址和指定端口 映射指定地址 宿主机端口随机分配 指定传输协议 端口暴露 容器互联 自定义网络 现在把container7加入到demo_net中 在启动一个容器加入到demo_net…

Linux进程(二)

文章目录 进程&#xff08;二&#xff09;Linux的进程状态R &#xff08;running&#xff09;运行态S &#xff08;sleeping&#xff09;阻塞状态D &#xff08;disk sleep&#xff09;深度睡眠T&#xff08;stopped&#xff09;状态X&#xff08;dead&#xff09;状态Z&#x…

数据结构 二叉树(C语言实现)

绪论 雄关漫道真如铁&#xff0c;而今迈步从头越。 本章将开始学习二叉树&#xff08;全文共一万两千字&#xff09;&#xff0c;二叉树相较于前面的数据结构来说难度会有许多的攀升&#xff0c;但只要跟着本篇博客深入的学习也可以基本的掌握基础二叉树。 话不多说安全带系好&…

关于 Ubuntu 长按 shift 无效, 按 Esc 直接进入 grub 改密码的解决方法

本次长按shift没有反应&#xff0c;直接进入了系统界面&#xff0c;所以改用长按Esc键&#xff0c;步骤如下&#xff1a; 1. 长按esc&#xff0c;进入grub>提示 2.输入grub>normal &#xff0c;回车 3.上一步回车后&#xff0c;继续敲击Esc &#xff0c;出现grub界面 …

HCIP---OSPF的优化

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.汇总&#xff1a; 目的&#xff1a;减少骨干区域的LSA的更新量 作用&#xff1a;OSPF的…

可缝合神经网络

文章目录 Stitchable Neural Networks摘要本文方法实验结果 Stitchable Neural Networks 摘要 包含大量强大的预训练模型族(如ResNet/DeiT)的model zoo已经达到了前所未有的范围&#xff0c;这对深度学习的成功有重要贡献。由于每个模型族都由具有不同尺度的预训练模型(例如&…

Linux 匿名页的生命周期

目录 匿名页的生成 匿名页生成时的状态 do_anonymous_page缺页中断源码 从匿名页加入Inactive lru引出 一个非常重要内核patch 匿名页何时回收 本文以Linux5.9源码讲述 匿名页的生成 用户空间malloc/mmap(非映射文件时&#xff09;来分配内存&#xff0c;在内核空间发生…

Docker实战-关于Docker镜像的相关操作(二)

导语   之前的分享中&#xff0c;我们介绍了关于Docker镜像的查询操作相关的内容&#xff0c;下面我们继续来介绍删除清理、导入导出、创建镜像等操作。 如何删除和清理镜像&#xff1f; 使用标签删除镜像 可以使用docker rmi 或者是 docker image rm 命令来删除镜像&#x…

Spring源码之XML文件中Bean标签的解析1

读取XML文件&#xff0c;创建对象 xml文件里包含Bean的信息&#xff0c;为了避免多次IO&#xff0c;需要一次性读取xml文件中所有bean信息&#xff0c;加入到Spring工厂。 读取配置文件 new ClassPathResource("applicationContext.xml")ClassPathResource是Sprin…

微信小程序nodejs+vue+uniapp高校食堂线上预约点餐系统

本次设计任务是要设计一个食堂线上预约点餐系统&#xff0c;通过这个系统能够满足管理员及学生的食堂线上预约点餐分享功能。系统的主要包括首页、个人中心、学生管理、菜品分类管理、菜品管理、关于我们管理、意见反馈、系统管理、订单管理等功能。 开发语言 node.js 框架&am…

Flink之RedisSink

在Flink开发中经常会有将数据写入到redis的需求,但是Flink官方并没有对应的扩展包,这个时候需要我们自己编译对应的jar资源,这个时候就用到了bahir,barhir是apahce的开源项目,是专门给spark和flink提供扩展包使用的,bahir官网,这篇文章就介绍下如何自己编译RedisSink扩展包. 下…

Prometheus服务器、Prometheus被监控端、Grafana、Prometheus服务器、Prometheus被监控端、Grafana

day03 day03Prometheus概述部署Prometheus服务器环境说明&#xff1a;配置时间安装Prometheus服务器添加被监控端部署通用的监控exporterGrafana概述部署Grafana展示node1的监控信息监控MySQL数据库配置MySQL配置mysql exporter配置mysql exporter配置prometheus监控mysql自动…

spring security + oauth2 使用RedisTokenStore 以json格式存储

1.项目架构 2.自己对 TokenStore 的 redis实现 package com.enterprise.auth.config;import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis…

Spring Boot、Spring Cloud、Spring Alibaba 版本对照关系及稳定兼容版本

Spring Boot、Spring Cloud、Spring Alibaba 版本对照关系及稳定兼容版本 引言 在 Java 生态系统中&#xff0c;Spring Boot、Spring Cloud 和 Spring Alibaba 是非常流行的框架&#xff0c;它们提供了丰富的功能和优雅的解决方案。然而&#xff0c;随着不断的发展和更新&…