【Java中常见的异常及其处理方式】
🌈个人主页: Aileen_0v0
🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法
💫个人格言:“没有罗马,那就自己创造罗马~”
文章目录
- 字符串修改的实现——StringBuilder和StringBuffer
- 异常
- 常见异常
- ①算数异常
- ②数组越界异常
- ③空指针异常
- Error
- 异常处理
- throw - 抛出异常(一般是自定义的异常)
- 异常捕获 - 两种方法:throws 和 try-catch
- 小结:
- finally - 无论是否发生异常finally后面的语句都会被执行,用于关闭资源。
- 异常处理流程梳理总结
- 自定义异常
- 总结
字符串修改的实现——StringBuilder和StringBuffer
通过查看Structure的结构我们可知:StringBuilder 的的方法基本上可以归为5种,分别是:
append
,delete
,replace
,insert
,indexOf
其中最关键的是“append”,使用案例如下所示:
public class Main {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("123");stringBuffer.append("abc").append("excellent");System.out.println(stringBuffer);StringBuilder stringBuilder = new StringBuilder("Hi");stringBuilder.append(" Hello");stringBuilder.append(" Aileen ").append("How are you?");System.out.println(stringBuilder);}
}
通过查看StringBuffer和StringBuilder这两个方法的append方法的重写,我们可以得出:这两个方法最主要的区别如下:
-
1. StringBuffer方法 : 有关键字synchronized【同步的】修饰,当它进入StringBuffer这个方法时,只有当这个方法里面的append执行完以后,才会执行其他方法的append,否则就不能执行其它对象的append,这意味着这个
StringBuffer方法适用于多线程情况
。(eg:多人排队上一个卫生间,只有当卫生间里面没人了下一个人才能进去上厕所。) -
2. StringBuilder方法 : 对于StringBulider方法,由于他没有synchronized这个关键字修饰,所以它适用于单线程情况下,若代码未涉及线程情况,选用StringBuilder即可。
-
频繁上锁和解锁需要耗费系统资源。
-
3. String变为StringBuilder: 利用StringBuilder的构造方法或append()方法。
-
4. StringBuilder变为String: 调用toString方法。
public class Main {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("123");stringBuffer.append("abc").append("excellent");System.out.println(stringBuffer);StringBuilder stringBuilder = new StringBuilder("Hi");stringBuilder.append(" Hello");stringBuilder.append(" Aileen ").append("How are you?");System.out.println(stringBuilder);System.out.println("=================================");
// 将stringBuilder转化成:stringString str = stringBuilder.toString();System.out.println(str);System.out.println("----------------------------------");// 将string转换成stringBuilder - 调用构造方法String str1 = "aileen";StringBuilder stringBuilder1 = new StringBuilder(str1);System.out.println(stringBuilder1);System.out.println("----------------------------------");
//StringBuilder stringBuilder2 = new StringBuilder();stringBuilder2.append(str1);System.out.println(stringBuilder2);}
}
- 字符串不可改变的原因是因为这个数组是被private修饰的,并且未提供get()和set()方法
面试题 |
-
1.String,StringBuffer,StringBuilder三者有什么区别?
- String的内容不可修改,StringBuffer和StringBuilder的内容可修改。
- StringBuffer与StringBuilder的大部分功能是相似的。
- StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作。
异常
常见异常
①算数异常
②数组越界异常
public static void main(String[] args) {int[] array = {1,2,3,4};System.out.println(array[10]);System.out.println("after");}
③空指针异常
public static void main(String[] args) {int[] array = null;System.out.println(array[10]);System.out.println("Hi");}
Error
public static void func(){func();}public static void main(String[] args) {func();}
异常处理
throw - 抛出异常(一般是自定义的异常)
public static void func2(int[] array){if(array == null){throw new NullPointerException("array == null 了!");}}public static void main(String[] args) {func2(null);}
异常一旦抛出,后面的代码就不会执行了。
异常捕获 - 两种方法:throws 和 try-catch
- 在没有实现Cloneable接口的情况下,通过throws捕获异常
class Person {public String name;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class ExceptionLearn {public static void main(String[] args) throws CloneNotSupportedException {Person p = new Person();Person p2 = (Person) p.clone();System.out.println("hi");}}
-
上面运行结果小结:如果程序的异常并未被程序员处理,此时这个异常就会交给JVM处理。程序会立即终止
-
为了处理异常,我们加上Cloneable接口再次查看运行结果
-
同一时刻,系统只能抛出一个异常。
- 注意:
- 1.throws必须跟在方法的参数列表后面
- 2.声明的异常必须是Exception 或 Exception的子类
- 3.方法内部如果抛出了多个异常,throws后必须跟多个异常类型,之间用逗号隔开,如果抛出的多个异常之间有父子关系,直接声明父类即可。
因为throws抛出的异常有两种情况,一种是运行时异常;另一种是编译时异常。
而对于main方法,他会把func()这里调用抛出的异常当做一个编译时异常来处理,这就需要程序员手动处理。以下是处理的方式及过程:
1.通过throws对异常进行层层声明,,然后程序会将异常交给JVM处理,此时程序就会异常终止。
2.通过try-catch抛出异常,用时程序还能够继续向下执行。如果不在main方法中throws Exception,可以通过快捷键Alt+Enter
选中以下的内容。
public class Test
{public static void func() throws NullPointerException{int[] array = null;System.out.println(array.length);}public static void main(String[] args){try {func();//将可能出现异常的代码放这} catch (NullPointerException e) {//捕获对应的异常System.out.println("处理异常");}System.out.println("after");}
}
- 如果还想要具体的红色报错信息可以通过调用空指针异常声明的变量e去调用printStackTrace方法来输出。
如果未在catch处声明对应代码的异常,再次运行程序结果会怎么样呢?
public static void main(String[] args) {try{int[] array = {1,2,3,4,5};System.out.println(array[9]);}catch (NullPointerException e){e.printStackTrace();System.out.println("捕获到了空指针异常。。。");}System.out.println("after");}
通过上面的代码我们可以看出,如果我们没有将对应代码的异常通过catch去捕获,那么它就会通过我们的最后一道防线JVM去终止程序。
- 现在让我们将对应代码的异常通过catch去捕获:
我们看到对于异常代码我们运行完以后直接通过catch去捕获其对应的异常,而对于异常代码后面的sout语句它并未执行。
- 可以通过|分割捕获多个异常,但是缺点是无法知道具体是哪一个
public static void main(String[] args) {try {int[] array = {1, 2, 3, 4, 5};System.out.println(array[9]);}catch (NullPointerException | ArrayIndexOutOfBoundsException e){ //可以通过|分割捕获多个异常,但是缺点是无法知道具体是哪一个e.printStackTrace();System.out.println("捕获到空指针 | 数组越界异常......");}System.out.println("Aileen");
}
- 如果捕获的异常具有父子类关系情况下,要把父类放最后面
public static void main(String[] args) {int[] arr = {1,2,3};try{System.out.println("before");arr = null;System.out.println(arr[100]);System.out.println("after");}catch(NullPointerException e){//空指针异常,属于异常的子类e.printStackTrace();System.out.println("我是空指针异常~");}catch(Exception e){//可捕获到所有异常,所有异常的父类e.printStackTrace();}System.out.println("after try catch");}
小结:
想要用try catch
只是捕获简单的异常直接catchException
即可,如果想要知道具体的异常类型可使用多个catch去捕获这个异常的具体内容
。
finally - 无论是否发生异常finally后面的语句都会被执行,用于关闭资源。
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);try{int[] array = {1,2,3,4};System.out.println(array[10]);int a = scanner.nextInt();System.out.println(a);}catch (NullPointerException e){e.printStackTrace();System.out.println("捕获NullPointerException异常...");}catch (ArrayIndexOutOfBoundsException e){System.out.println("捕获ArrayIndexOutOfBoundsException异常...");}finally {System.out.println("finally被执行了");scanner.close();}System.out.println("after");}
import java.util.Scanner;public class Test {public static int func2() {Scanner scanner = new Scanner(System.in);try {int a = scanner.nextInt();System.out.println(a);} catch (NullPointerException e) {e.printStackTrace();System.out.println("捕获NullPointerException异常...");} catch (ArrayIndexOutOfBoundsException e) {System.out.println("捕获ArrayIndexOutOfBoundsException异常...");} finally {System.out.println("finally被执行了");scanner.close();}System.out.println("after");return -1;}public static void main(String[] args) {func2();}
根据上面的运行结果可以得出以下结论:当我们try-catch
捕获异常时,如果catch后面的异常跟我们出现的不匹配,它就会通过JVM
来找到异常,并且终止程序。上面的scanner需要我们输入数字但是我输入的是字符与需求不匹配,所以当程序运行到这里的时候会通过JVM
去捕获异常,然后终止程序,finally永远都会被执行,正因如此如果我们需要关闭资源我们可以将关闭资源的代码放入到finally的语句块中,从而节省程序的资源
。
import java.util.InputMismatchException;
import java.util.Scanner;public class Test {public static int func2() {Scanner scanner = new Scanner(System.in);try {int a = 10;return a;} catch (InputMismatchException e) {e.printStackTrace();System.out.println("捕获InputMismatchException异常...");} finally {System.out.println("finally被执行了");scanner.close();return 99;}}public static void main(String[] args) {System.out.println(func2());}
异常处理流程梳理总结
- 程序先执行
try
中的代码 - 如果
try
中的代码出现异常,就会结束try
中的代码,看和catch中的异常类型是否匹配。 - 如果找到匹配的异常类型,就会执行
catch
中的代码 - 如果没有找到匹配的异常类型,就会将异常向上传递到上层调用者。
- 无论是否匹配到匹配的异常类型,
finally
中的代码都会被执行到(在该方法结束前执行)。 - 如果上层调用者也没有处理的异常了,就继续向上传递。
- 一直到main方法也没有合适的处理异常的代码,就会交给
JVM
来处理,此时程序就会异常终止。
自定义异常
import java.util.InputMismatchException;
import java.util.Scanner;class Login{public String userName = "Aileen";public String passWord = "123456";public void logIn(String userName , String passWord){if(!this.userName.equals(userName)){System.out.println("用户名错误!");}if(!this.passWord.equals(passWord)){System.out.println("密码错误!");}}
}public class Test {public static void main(String[] args) {Login login = new Login();login.logIn("Aileen","abcd");}
我们可以通过自定义方法来找到错误点但是无法定位到错误的位置,为了实现这个功能,我们可以自定义一个异常类,来定位错误,我们可以通过模仿已有的异常来编写自定义异常的类:
我们可以看到已有异常继承于运行时异常这个类,并且还调用了其无参构造方法和带有一个参数的构造方法。
- 自定义异常可以继承Exception和RuntimeException
- 通过关键字
throw
来抛出对应的自定义异常
import java.util.InputMismatchException;
import java.util.Scanner;class Login{public String userName = "Aileen";public String passWord = "123456";public void logIn(String userName , String passWord){if(!this.userName.equals(userName)){
// System.out.println("用户名错误!");throw new UserNameException("用户名错误!");}if(!this.passWord.equals(passWord)){
// System.out.println("密码错误!");throw new PassWordException("密码错误!");}}
}public class Test {public static void main(String[] args) {try{Login login = new Login();login.logIn("Aileen","abcd");}catch (UserNameException e){e.printStackTrace();System.out.println("捕捉到了用户名错误异常。。。");}catch (PassWordException e){e.printStackTrace();System.out.println("捕捉到了密码错误异常。。。");}System.out.println("程序继续执行");}
- 以下两个类是参照运行时异常的源代码修改的自定义异常代码:
- ①.密码错误类
- ②.用户名异常类
- ①.密码错误类
总结
相关文章:

【Java中常见的异常及其处理方式】
🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 💫个人格言:“没有罗马,那就自己创造罗马~” 文章目录 字符串修改的实现——StringBuilder和StringBuffer异常常见异常①算数异常②数组越界异常③空指针异…...
如何更新项目中的 npm 或 Yarn 依赖包至最新版本
要升级 package.json 文件中列出的包,你可以使用 npm(Node Package Manager)或 yarn。以下是两种工具的命令来更新你的依赖项: 使用 npm 更新所有包到最新版本 npm update如果你想将所有依赖项更新到其各自最新的大版本…...

SpringBoot3整合FastJSON2如何配置configureMessageConverters
在 Spring Boot 3 中整合 FastJSON 2 主要涉及到以下几个步骤,包括添加依赖、配置 FastJSON 作为 JSON 处理器等。下面是详细的步骤: 1. 添加依赖 首先,你需要在你的 pom.xml 文件中添加 FastJSON 2 的依赖。以下是 Maven 依赖的示例&#…...

《Vue3实战教程》2:Vue3快速上手
如果您有疑问,请观看视频教程《Vue3实战教程》 快速上手 线上尝试 Vue 想要快速体验 Vue,你可以直接试试我们的演练场。 如果你更喜欢不用任何构建的原始 HTML,可以使用 JSFiddle 入门。 如果你已经比较熟悉 Node.js 和构建工具等概念…...
ubuntu 24.04.1安装FTP流程
1、安装vsftpd: sudo apt update sudo apt install vsftpd 2、安装后重启查看vsftpd状态 sudo systemctl status vsftpd 输出如下所示,表明vsftpd服务处于活动状态并正在运行: * vsftpd.service - vsftpd FTP server Loaded: loaded (/…...

多功能护照阅读器港澳通行证阅读机RS232串口主动输出协议,支持和单片机/Linux对接使用
此护照阅读器支持护照、电子芯片护照、港澳通行证、台湾通行证,和串口的被动的方式不一样。此护照阅读器通电后,自动读卡,串口输出,软件只需要去串口监听数据即可,例如用串口助手就可以收到读卡信息。 非常适用于单片…...
5个用于构建Web应用程序的Go Web框架
探索高效Web开发的顶级Go框架 Go(或称为Golang)以其简洁性、高效性和出色的标准库而闻名。然而,有几个流行的Go Web框架和库为构建Web应用程序提供了额外的功能。以下是五个最值得注意的Go框架: 1. Gin: Gin是一个高…...

Qt中的异步相关类
Qt中的异步相关类 今天在学习别人的项目时,看到别人包含了QFuture类,我没有见过,于是记录一下。 直接在AI助手中搜索QFuture,得到的时Qt中异步相关的类。于是直接查询一下Qt异步中相关的类。 在Qt中,异步编程是一个重要的概念&…...
浅谈仓颉语言的优劣
仓颉语言,作为华为自研的新一代编程语言,以其高效、安全、现代化的特点,引起了广泛的关注。 仓颉语言的优势 高效并发 仓颉语言的一大亮点是其轻松并发的能力。它实现了轻量化用户态线程和并发对象库,使得高效并发变得轻松。仓颉…...
Linux 显示系统活动进程状态命令 ps 详细介绍
Linux 和类 Unix 操作系统中的 ps(Process Status)命令用于显示当前系统中活动进程状态的命令。它提供了关于系统中正在运行的进程的详细信息,如进程 ID(PID)、父进程 ID(PPID)、运行时间、使用…...

scala中正则表达式的使用
正则表达式: 基本概念 在 Scala 中,正则表达式是用于处理文本模式匹配的强大工具。它通过java.util.regex.Pattern和java.util.regex.Matcher这两个 Java 类来实现(因为 Scala 运行在 Java 虚拟机上,可以无缝使用 Java 类库&…...

数据分析和AI丨知识图谱,AI革命中数据集成和模型构建的关键推动者
人工智能(AI)已经吸引了数据科学家、技术领导者以及任何使用数据进行商业决策者的兴趣。绝大多数企业都希望利用人工智能技术来增强洞察力和生产力,而对于这些企业而言,数据集的质量差成为了最主要的障碍。 数据源需要进行清洗且明…...

cocos creator制作2dTop-down游戏(虚拟摇杆、地图加载)
《不被遗忘的时光》第一期 1、游戏的形式:横板;2d的顶视角(Top-down);射击;ARPG;益智解谜。 2、画风:类似手游《伊洛纳》。 3、故事背景:以中元节的爷孙阴阳交流作为故…...
SQL Server 批量插入数据的方式汇总及优缺点分析
在 SQL Server 中,批量插入数据是非常常见的操作,尤其是在需要导入大量数据时。以下是几种常用的批量插入数据的方式: 1. 使用 INSERT INTO ... VALUES • 特点:适用于少量数据插入。 • 优点:简单易用。 • 缺点:不适合大量数据插入,性能较差。 • 示例:…...

linux上抓包RoCEv2
1、检查tcpdump版本 tcpdump help(4.99.4以上) 如果版本较低需要重新下载编译: wget https://www.tcpdump.org/release/libpcap-1.10.5.tar.xz wget http://www.tcpdump.org/release/tcpdump-4.99.4.tar.gz tar -xJf libpcap-1.10.5.tar.xz…...

【机器学习与数据挖掘实战】案例04:基于K-Means算法的信用卡高风险客户识别
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数…...

UDP网络编程套接
目录 本文核心 预备知识 1.端口号 认识TCP协议 认识UDP协议 网络字节序 socket编程接口 sockaddr结构 UDP套接字编程 服务端 客户端 TCP与UDP传输的区别 可靠性: 传输方式: 用途: 头部开销: 速度: li…...

期权VIX指数构建与择时应用
芝加哥期权交易 所CBOE的波动率指数VIX 是反映 S&P 500 指数未来 30 天预测期波动率的指标,由于预期波动率多用于表征市场情绪,因此 VIX 也被称为“ 恐慌指数”。 VIX指数计算 VIX 反映了市场情绪和投资者的风险偏好, 对于欧美市场而言…...
QT笔记- QClipboard剪切板对QByteArray数据的复制与粘贴
复制 // 存储在剪切板 QByteArray data; QClipboard * clipboard QGuiApplication::clipboard(); // 获取系统剪贴板对象 QMimeData * mimeData new QMimeData; // 注意, 剪切板会接管对象的释放 QString customMimeType "Test"; // 设置数据标识, 粘贴时将根据…...
Python使用PyMySQL操作MySQL完整指南
Python使用PyMySQL操作MySQL完整指南 1. 安装依赖 pip install pymysql2. 基础配置和数据库操作 2.1 基础配置类 import pymysql from typing import List, Dict, Optional from datetime import datetimeclass MySQLDB:def __init__(self):self.conn Noneself.cursor No…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...