当前位置: 首页 > news >正文

人生在世皆有过错,来一起看看Java中的异常吧!!!

Java中的异常问题详解

一、异常的概念与分类

1.异常概念

概念:Java异常是一个描述在代码段中发生异常的对象,当发生异常情况时,一个代表该异常的对象被创建并且在导致该异常的方法中被抛出,而该方法可以选择自己处理异常或者传递该异常。

异常机制:异常机制是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。

2.关于异常的分类

(1)非受查异常(运行时异常):是指程序在执行时出现的异常

举例Demo:

int[] array = null;
System.out.println(array.length);//执行结果:
Exception in thread "main" java.lang.NullPointerExceptionat TestDemo.main(TestDemo.java:160)
//必须对其进行捕获或声明以便抛出    

(2)受查异常(编译时异常):是指程序在进行编译时出现的异常

(3)逻辑错误:是指因为程序没有按照预期的逻辑顺序执行。异常也就是指程序运行时发生错误,而异常处理就是对这些错误进行处理和控制

3.常见的异常

(1)算术异常

Demo:

int a = 10;
System.out.println(a/0);//执行结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
//0不能放在分母    

(2)数组越界异常

Demo:

int[] array = {1,2,3};
System.out.println(array[4]);//执行结果:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 3

(3)空指针异常

Demo:

int[] array = null;
System.out.println(array.length);//执行结果:
Exception in thread "main" java.lang.NullPointerException

二、异常的体系结构

在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。

在这里插入图片描述

在图中可以看出

  • Throwable有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。异常和错误的区别是:异常能被程序本身可以处理,错误是无法处理。
  • Error指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表: StackOverflowError和OutOfMemoryError。
  • Exception是程序本身可以处理的异常。Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。
  • Exception:分为运行时异常和非运行时异常。

三、异常的处理方式

1.防御式处理

防御式处理是指程序猿在写代码时就要有这种意识,写一步代码就会做一次检查。

如以下例子:

Demo:

boolean ret = false;
ret = 登陆游戏();
if (!ret) {
处理登陆游戏错误;return;
}
ret = 开始匹配();
if (!ret) {
处理匹配错误;return;
}
ret = 游戏确认();
if (!ret) {
处理游戏确认错误;return;
}
ret = 选择英雄();
if (!ret) {处理选择英雄错误;return;
}
ret = 载入游戏画面();
if (!ret) {
处理载入游戏错误;return;
}

2.事后认错型处理

事后认错型处理就是指先执行代码,如果遇到问题,再去处理问题。

(1).try···catch···异常捕获和处理

try {登陆游戏();开始匹配();游戏确认();选择英雄();载入游戏画面();...
} catch (登陆游戏异常) {处理登陆游戏异常;
} catch (开始匹配异常) {
处理开始匹配异常;
} catch (游戏确认异常) {
处理游戏确认异常;
} catch (选择英雄异常) {
处理选择英雄异常;
} catch (载入游戏画面异常) {
处理载入游戏画面异常;
}

注:

  • try当中的存放可能出现的异常代码
  • catch当中捕获可能出现的异常

Demo:

try {int a = 10;System.out.println(a/0);System.out.println("正常代码!");
}catch (ArithmeticException e) {e.printStackTrace();//快速地定位异常出现的位置System.out.println("你这里出现了算术异常!");
}//执行结果:
java.lang.ArithmeticException: / by zeroat TestDemo.main(TestDemo.java:161)
你这里出现了算术异常!

从上面的结果可以看出,当代码运行到有错误的代码的时候,就会抛出异常,由catch去捕获异常,就不会继续执行后面正常的代码

关于try···catch···的使用细节

(1)如果try中出现了多个异常,当catch去捕捉时可用‘|’去分开各个异常.

catch (ArithmeticException | NullPointerException e)

(2)如果catch中没有写出对应的异常,这里就不会去捕获,最终这个异常就会交给JVM去处理,程序就会立即终止,正常的代码也不会执行.

(3)不会同时出现两个及以上异常

原因:因为当出现一个异常,就会直接被catch捕获,就不会继续执行try中的语句了.

(4)不建议这样写

catch(Exception e) {}

这样写说明你这人懒啊!!!

(5)try当中可能会同时抛出多个不同的异常对象,则必须用多个catch去捕获——多个异常,多次捕获.

(6)

catch(Exception e) {}catch(ArithmeticException e) {}

由于Exception是所有类的父类,那么后面的子类就没有存在的必要,所有这种写法不可行!!!

但是当父类Exception和子类交换位置时,这种写法是可行的.

(2)异常的声明

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

语法格式:

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

具体代码举例:

Demo:

public class TestDemo {public static void test(int a) throws CloneNotSupportedException {if (a == 10) {throw new CloneNotSupportedException();}System.out.println("异常后的代码不执行!");}public static void main(String[] args) {try {test(10);System.out.println("正常代码!");}catch (CloneNotSupportedException e) {e.printStackTrace();}}
}//执行结果:
java.lang.CloneNotSupportedException

注意事项:

  • throw必须写在方法体内部
  • 抛出的对象必须是Exception或者Exception子类的对象
  • 如果抛出的是Runtime Exception或者Runtime Exception的子类,则可以不用处理,交给JVM就行
  • 如果抛出的是编译异常,就必须处理,否则编译无法通过
  • 异常一旦抛出,异常后面的代码就不会执行

(3)关于finally关键字

finally:一般用于资源释放,断开连接,关闭管道流等

一般搭配try – catch --finally 或者 try — finally,一般来说无论try中是否抛出异常,都会执行finally。

Demo:

public class TestDemo {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);try {int num = scanner.nextInt();System.out.println(num);}catch (InputMismatchException e) {e.printStackTrace();System.out.println("输入的数据不匹配!");}finally {System.out.println("执行了finally部分,一般用来关闭资源!");scanner.close();}}
}

在这里插入图片描述

这种就是正确的输入。

在这里插入图片描述

这种就是错误的输入,代码叫我们输入一个数字,但是这里我们输入了字符串,就会出现输入异常

但是finally部分的代码不管出现异常没有都会执行

(4)关于异常处理的流程

  • 如果try中有异常,就会抛出异常,由catch捕获,然后匹配是否有配对的异常
  • 如果有就执行catch中的语句
  • 如果没有就会将异常上传给上层调用者
  • 无论有没有都会执行finally中的语句
  • 如果上层调用者也没有,就会继续上传
  • 一直到main方法,如果main方法中也没有,就会将其交给JVM,此时程序机会异常终止

(5)finally的注意事项

建议不要在finally中return 数据!!!

因为finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。也就是说try块中的return值会先保存起来,然后执行完finally中的代码后,才会把try块中的return值返回,所以finally中的代码逻辑是不会影响try块中的return值的。但如果在finally中使用return了就会导致try块中的代码得不到执行而无法返回正确的结果。

例子:

public class TestDemo {public static int func() {int num = 10;try{return num;}catch (Exception e){e.printStackTrace();} finally {num = 5;return num;}}public static void main(String[] args) {int ret = func();System.out.println(ret);}
}//执行结果:
5

四、自定义异常

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

具体方式:

格式:public class XXXException extends Exception 或者 RuntimeException{

添加一个空参数的构造方法

添加一个带异常信息的构造方法

}

Demo举例:

class UserNameErrorException extends RuntimeException {public UserNameErrorException() {super();}public UserNameErrorException(String message) {super(message);}
}
class PassWordErrorException extends RuntimeException {public PassWordErrorException() {super();}public PassWordErrorException(String message) {super(message);}
}
public class TestDemo {private String userName = "admin";private String passWord = "123456";public void LoginInto(String userName,String passWord) {try {if(!this.userName.equals(userName)) {throw new UserNameErrorException("用户名错误!");}if (!this.passWord.equals(passWord)){throw new PassWordErrorException("密码错误!");}System.out.println("登陆成功!");}catch (UserNameErrorException e) {e.printStackTrace();}catch (PassWordErrorException e) {e.printStackTrace();}}public static void main(String[] args) {TestDemo test = new TestDemo();test.LoginInto("admi","123456");}
}

第一种运行结果:当userName和passWord输入正确的时候

在这里插入图片描述

第二种运行结构:当userName和passWord其中有一个或者两个都不对的时候

在这里插入图片描述

在这里插入图片描述

注意事项:

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

好啦!关于java中的异常就讲到这里,如果各位小伙伴有问题或者发现本博客有什么问题,可以私信哦!!!

以蝼蚁之行,展鸿鹄之志

相关文章:

人生在世皆有过错,来一起看看Java中的异常吧!!!

Java中的异常问题详解 一、异常的概念与分类 1.异常概念 概念:Java异常是一个描述在代码段中发生异常的对象,当发生异常情况时,一个代表该异常的对象被创建并且在导致该异常的方法中被抛出,而该方法可以选择自己处理异常或者传…...

linux 测试连接网络和端口 telnet

一、安装telnet 1、检测telnet-server的rpm包是否安装 [rootlocalhost ~]# rpm -qa telnet-server 若无输入内容,则表示没有安装。出于安全考虑telnet-server.rpm是默认没有安装的,而telnet的客户端是标配。即下面的软件是默认安装的。 2、若未安装&…...

一文快速入门体验 Hibernate

前言 Hibernate 是一个优秀的持久层的框架,当然,虽然现在说用得比较多的是 MyBaits,但是我工作中也不得不接触 Hibernate,特别是一些老项目需要你维护的时候。所以,在此写下这篇文章,方便自己回顾&#xf…...

【RabbitMQ】SpringAMQP

RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应。 异步通讯:就像发邮件,不需要马上回复。 两种方式各有优劣,打电话可以立即得到响应&am…...

错题汇总08

1.如果友元函数重载一个运算符时,其参数表中没有任何参数则说明该运算符是 A 一元运算符 B 二元运算符 C 选项A)和选项B)都可能 D 重载错误 运算符重载 1.重载成类的成员函数------>形参数目看起来比该运算符需要的参数个数少1&#x…...

使用urllib库简单入门

使用urllib库简单入门 Python中的urllib库是一个非常强大的工具,它提供了一些模块,如urllib.request、urllib.parse、urllib.error、urllib.robotparser等,可以用来处理URLs和网页数据的获取、发送和处理。 在本文中,我们将介绍…...

C++学习 Day11

目录 1. 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 2. stastic成员 2.1 概念 2.2 特性 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 class Date…...

python中函数与类 类中的方法-静态方法/动态方法

class student():position即令def __init__(self,name,age):self.namenameself.ageagedef eat(self):passclassmethoddef cla(cls):passstaticmethoddef sta():passpassstustudent(name张三,age12) print(stu.position)stu.sta() stu.cla()# 直接使用静态和类方法 student.cla(…...

基于trace_id实现ForkJoinPool的链路追踪

一、引言 之前写过一篇博客:基于trace_id的链路追踪(含Feign、Hystrix、线程池等场景),主要介绍在微服务体系架构中,如何实现分布式系统的链路追踪的博客,其中主要实现了以下几种场景: Filter…...

Qt推流程序(视频文件/视频流/摄像头/桌面转成流媒体rtmp+hls+webrtc)可在网页和播放器远程观看

一、前言说明 推流直播就是把采集阶段封包好的内容传输到服务器的过程。其实就是将现场的视频信号从手机端,电脑端,摄影机端打包传到服务器的过程。“推流”对网络要求比较高,如果网络不稳定,直播效果就会很差,观众观…...

ChatGPT入门到高级【第一章】

第一章:Chatgpt的起源和发展 1.1 人工智能和Chatbot的概念 1.2 Chatbot的历史发展 1.3 机器学习技术在Chatbot中的应用 1.4 Chatgpt的诞生和发展 第二章:Chatgpt的技术原理 2.1 自然语言处理技术 2.2 深度学习技术 2.3 Transformer模型 2.4 GPT模型 第…...

云原生应用架构

本博客地址:https://security.blog.csdn.net/article/details/130566883 一、什么是云原生应用架构 成为云原生应用至少需要满足下面几个特点: ● 使用微服务架构对业务进行拆分。单个微服务是个自治的服务领域,对这个领域内的业务实体能够…...

rem、px、em的区别 -前端

文章目录 三者的区别特点与换算举例emrem 总结一总结二 三者的区别 在css中单位长度用的最多的是px、em、rem,这三个的区别是: 一、px是固定的像素,一旦设置了就无法因为适应页面大小而改变。 二、em和rem相对于px更具有灵活性,…...

分享几款小白从零开始学习的会用到的工具/网站

大二狗接触编程也有两年了,差生文具多这大众都认可的一句话,在这里蹭一下这个活动分享一下从0开始学习编程有啥好用的工具 目录 伴侣一、Snipaste截图工具 伴侣二、Postman软件(可用ApiPost平替) 伴侣三、字体图标网站 伴侣四…...

第八章 文件处理命令

第八章 文件处理命令 一、 文本编辑器 vi • vi 是 Unix 类操作系统中最为流行的文本编辑器。尽管目前 已有 gedit 等一些工作在图形界面下使用起来也更为方便 的文本编辑器,但在很多情况下,vi 这种专为字符界面操 作而设计的编辑器恐怕还是要充当首…...

LVS 负载均衡群集的 NAT 模式和 DR 模式

1. 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 DR 模式 * 负载各节点服务器通过本地网络连接,不需要建立专用的IP隧道 原理:首先负载均衡器接收到客户的请求数据包时,根据调度算法决定将请求发送给哪个后端的…...

自学自动化测试,第一份工作就18K,因为掌握了这些技术

我个人的情况是有1年自动化测试工作经验半年的实习经验,2020年毕业,专业通信工程,大一的时候学过C语言,所以一直对于编程感兴趣,之所以毕业后没做通信的工作,通信行业的朋友应该都明白,通信的天…...

C++ 类的继承与派生

目录 1、继承的概念 2、继承(Inherit) 3、继承方式 4、父子同名成员并存 5、虚函数(virtual) 6、纯虚函数 1、继承的概念 以李白为例 类1是类2的基类(父类),类2是类3的基类(父类…...

分布式系统基础理论

CAP是分布式系统方向中的一个非常重要的理论,可以粗略的将它看成是分布式系统的起点,CAP分别代表的是分布式系统中的三种性质,分别是Consistency(可用性)、Availability(一致性)、Partition tol…...

HttpServletRequestWrapper的使用与原理

​ 介绍 HttpServletRequestWrapper 实现了 HttpServletRequest 接口,可以让开发人员很方便的改造发送给 Servlet 的请求.HttpServletRequest 对参数值的获取实际调的是org.apache.catalina.connector.Request没有提供对应的set方法修改属性所以不能对前端传来的参…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

TMC2226超静音步进电机驱动控制模块

目前已经使用TMC2226量产超过20K,发现在静音方面做的还是很不错。 一、TMC2226管脚定义说明 二、原理图及下载地址 一、TMC2226管脚定义说明 引脚编号类型功能OB11电机线圈 B 输出 1BRB2线圈 B 的检测电阻连接端。将检测电阻靠近该引脚连接到地。使用内部检测电阻时,将此引…...

ubuntu自定义服务自动启动

自定义服务 在路径 /etc/systemd/system/ 下 定义example.service [Unit] DescriptionMy Custom Script[Service] ExecStart/root/exe_start.sh Typeoneshot RemainAfterExityes[Install] WantedBymulti-user.target在/root/ 路径下执行 vi exe_start.shcd /root/mes_server/…...

【AI大模型】Transformer架构到底是什么?

引言 —— 想象一台能瞬间读懂整本《战争与和平》、精准翻译俳句中的禅意、甚至为你的设计草图生成前端代码的机器——这一切并非科幻&#xff0c;而是过去七年AI领域最震撼的技术革命&#xff1a;Transformer架构创造的奇迹。 当谷歌在2017年揭开Transformer的神秘面纱时&…...