【Java中常见的异常及其处理方式】
](https://i-blog.csdnimg.cn/blog_migrate/576340a359de17e3fcd2b936316c88cf.png#pic_center)
🌈个人主页: 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("程序继续执行");}

- 以下两个类是参照运行时异常的源代码修改的自定义异常代码:
- ①.密码错误类

- ②.用户名异常类

- ①.密码错误类
总结

](https://i-blog.csdnimg.cn/blog_migrate/a3933983f953d71ef6bad48b225f5ec5.gif#pic_center)
](https://img-blog.csdnimg.cn/cc002cbd5c414c5393e19c5e0a0dbf20.gif#pic_center#pic_center)
相关文章:
【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…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
