05 JavaSE-- 异常、IOStream、多线程、反射、Annotation、泛型、序列化
Exception 异常
- 异常也是对象,也有自己的体系,在这个体系中,所有异常对象的根类是 throwable 接口。
- 异常和 error 错误是不同的概念。
错误是严重的 JVM 系统问题,一般不期待程序员去捕获、处理这些错误,同时,也不应期待程序不会从错误中恢复。
当发生错误时,通常意味着应用程序已经无法正常执行,最好的做法是记录错误信息然后终止程序。

- Java 提供了以下关键字和类来支持异常处理:
- try:用于包裹可能会抛出异常的代码块。
- catch:用于捕获异常并处理异常的代码块。
- finally:用于包含无论是否发生异常都需要执行的代码块。
- throw:用于手动抛出异常。
- throws:用于在方法声明中指定方法可能抛出的异常。
- Exception 类:是所有异常类的父类,它提供了一些方法来获取异常信息,如 getMessage()、printStackTrace() 等。
- 在 Java 中,异常分为两种:
- Checked Exceptions 检查(强制)性异常:必须提前在代码中处理的异常,如果不处理编译器报错。
- Unchecked / RunTime Exceptions 非检查性(运行时)异常:可以在代码中选择性处理的异常,即使不处理也能不报错编译通过
1. Checked Exceptions 检查性/强制性/编译时异常
- 强制性异常是由编译器检查到的异常
- 强制性异常必须提前在程序中写好代码处理。要么通过 try-catch语句捕获,要么通过方法签名声明抛出。
- 强制性异常通常是由
外部因素引起的,例如文件不存在、网络连接中断等。 - 强制性异常必须在代码中显式处理,要么通过 try-catch 块捕获并处理,要么通过在方法签名中使用 throws 关键字声明该异常,以通知调用者处理。
try {// 可能会抛出 IOException 的代码
} catch (IOException e) {// 处理 IOException
}
public void readFile() throws IOException {// 可能会抛出IOException的代码
}
2. Unchecked / RunTime Exceptions 非检查性(运行时)异常
- 运行时异常是在运行时抛出的异常
- 运行时异常无需提前在程序中设置捕获语句进行处理。
- 运行时异常通常是由程序
内部错误引起的,例如空指针引用、数组越界等。 - 运行时异常通常是由程序员在编写代码时可以避免的,因此也称为“非强制性”异常。
3. 处理异常
- 异常的处理包括两种方式:
- 声明异常:类似于推卸责任的处理方式
在方法定义时使用 throws 关键字声明异常,告知调用者,调用这个方法可能会出现异常,但自身并不处理。这种处理方式的态度是:如果出现了异常则会抛给调用者来处理。 - 捕获异常:真正的处理
在可能出现异常的代码上使用 try-catch 进行捕获处理。这种处理方式的态度是:把异常抓住。
- 声明异常:类似于推卸责任的处理方式
4. 手动抛出异常 throw
- 程序在运行中检测到错误后,可以创建一个合适类型的异常实例并抛出它
- 在同一方法内先用 throw 抛出异常,再用 try-catch 捕获没有任何作用。正确的做法是调用该方法的方法内,用try-catch 捕获
- 手动抛出的异常有两种, 分别为运行时异常和编译时异常.、
- 抛出运行时异常时,可以不用处理抛出的这个异常.
- 抛出编译时异常时,必须要处理抛出的这个异常,否则编译不能通过
/** divide 方法内部检查了除数是否为 0,如果是,则使用 throw 关键字抛出一个 ArithmeticException。- 调用这个方法的代码块通过 try-catch 捕获了这个异常,并在 catch 块中处理了这个错误情况*/ public static double divide(double chushu, double beichushu) throws ArithmeticException {// 事实上,即使不手动抛出,JVM 也会检测到该运行时异常,自动抛出// 因此下面三行代码有没有,输出结果都一样if (beichushu == 0) {throw new ArithmeticException("除数不能为零");}return beichushu / chushu;}public static void main(String[] args) {try {double result = divide(10, 0);System.out.println("结果是: " + result);} catch (ArithmeticException e) {System.err.println("发生错误: " + e.getMessage());}}

public class ThrowEx {// 手动抛出运行时异常,可以不处理public void setAge(int age) {if (age < 0) {throw new NullPointerException("输入的年龄小于0");}}// 手动抛出编译时异常,调用该方法者必须要处理这个异常public void setAge2(int age) throws FileNotFoundException {if (age < 0) {throw new FileNotFoundException("输入的年龄小于0");}}public static void main(String[] args) {ThrowEx throwEx = new ThrowEx();// 首先明确,尽管方法 1, 2 都抛出了异常,但在调用方法种,并没有处理抛出的异常//方法 1 指定的异常是运行时异常,调用者不是必须处理这个异常,编译也能通过//方法 2 指定的异常是编译时异常,由于调用者没有处理,因此无法编译通过throwEx.setAge(-5);//throwEx.setAge2(-5);}
调用方法 1 时,正常编译构建,并送出错误提示

调用方法 2 时,无法通过编译构建

同时调用方法1,2时,依然无法通过编译构建,这验证了之前说过的话:抛出编译时异常时,必须要处理抛出的这个异常,否则编译不能通过。
5. 自动捕获异常 try-catch-finally
- 使用 try-catch-finally 处理编译时异常,是让程序在编译时就不再报错,但是运行时仍然有可能报错。相当于我们使用 try-catch 将一个编译时可能出现的异常,延迟到运行时出现。
- 在开发中,运行时异常比较常见,此时一般不用 try-catch 去处理,因为处理和不处理都是一个报错,最好办法是去修改代码。
- try 和 catch 必须配对使用,finally 则没有强制要求
- try 语句块中:放的是可能出现问题的代码,尽量不要把不相关的代码放入到里面,否则会出现截断的问题。
- catch 括号中,声明想要捕获的异常类型;语句块中,放置捕获指定异常后处理问题的代码,如果问题在 try 语句块中没有出现,则 catch 不会运行。
- finally 语句块中:放的是不管问题异常是否产生,都要执行的代码。
/**Integer.parseInt(str)方法将 str 转换为整数。但由于str的内容不是有效的整数(它包含字母而非数字),- 这个操作将会抛出一个 NumberFormatException。- catch 括号中声明本次捕获目标是 NumberFormatException,如果发生此异常,将执行该块中的代码,即 e.printStackTrace()。- 第二个 catch 括号中声明本次捕获目标是 Exception,由于 Exception 本就是所有异常的根类- 因此第二个 catch 可以捕获除 NumberFormatException 之外的所有异常类型(前提是这些异常没有在第一个 catch 块中被捕获)。- 这里,如果捕获到任何其他异常,程序将输出e.getMessage(),即异常的描述信息。- finally块:无论是否发生异常,finally块中的代码都会被执行。*/public static void main(String[] args) {String str = "avocado";try {int i = Integer.parseInt(str);} catch (NumberFormatException e) {e.printStackTrace();} catch (Exception e) {System.out.println(e.getMessage());} finally {System.out.println("运行完毕");}}

6. 声明异常 throws
- 在 Java 中,当前执行的语句必属于某个方法。
- 每个方法都必须声明它可能抛出的强制性异常的类型。
- 声明的方式是:在方法头使用 throws 关键字
public void myMethod throws Exceptionl, Exception2,… ,ExceptionN
- throws 一般用于方法中可能存在异常时,需要将异常情况向方法之上的层级抛出,由抛出方法的上一级来解决这个问题,如果方法的上一级无法解决的会就会再将异常向上抛出,最终会抛给 main 方法,这样一来 main 方法中调用了这个方法的时候,就需要解决这个可能出现的异常.
当然 main 方法也可以不解决异常,将异常往上抛给 JVM ,如果 JVM 也无法解决的话,那么 JVM 就 over 了 - try-catch-fianlly 真正将异常给处理掉了。throws 只是将异常抛给了方法的调用者,并没有真正将异常处理掉。
- 之前所述,子类重写父类方法时,不可以抛出新的强制性异常,或者比父类方法声明的更广泛的强制性异常。
7. 如何选择 try-catch-finally 和 throws
什么时候捕捉?什么时候声明?
如果异常发生后需要调用者来处理的,需要调用者知道的,则采用声明方式。否则采用捕捉。
- 同一方法内, try-catch 和 throws 不要同时使用。因为只要 try-catch 就已经将异常处理掉了,再 throws 没有任何意义
- 放眼整个程序,try-catch 和 throws 应当联合使用。
例如,在方法标签通过 throws 抛出异常,让调用者决定如何处理。而调用者使用 try-catch 捕获并处理这些异常。
- 如果父类的方法没有声明抛出任何检查型异常(Checked Exception),则子类在重写这个方法时也不能声明抛出检查型异常。因此,如果子类重写的方法中需要处理异常,必须在方法内部使用 try-catch-finally 进行处理。
如果父类的方法没有使用 throws 声明任何检查型异常,意味着该方法不抛出任何需要强制处理的检查型异常。
- 在一个复杂的调用链中,建议在较底层的方法中使用 throws 抛出异常,而在较高层的方法中使用 try-catch-finally 来处理这些异常。
假设我们有以下方法调用链:
方法 a 调用 方法 b
方法 b 调用 方法 c
在较底层的方法 b、c ,使用 throws 声明这些方法可能抛出的异常,而不在这些方法内部进行异常捕获和处理。这种做法有以下优点:
异常传播:将异常传递给调用者,让调用者决定如何处理。
简化代码:底层方法专注于核心逻辑,不必处理异常,从而简化代码。
public class Example {public static void methodC() throws Exception {if (someCondition) {throw new Exception("Method C exception");}// 方法 C 的其他逻辑}public static void methodB() throws Exception {methodC();// 方法 B 的其他逻辑}public static void methodA() {try {methodB();} catch (Exception e) {System.err.println("发生错误: " + e.getMessage());} finally {System.out.println("清理操作");}}public static void main(String[] args) {methodA();}
}
高层方法使用 try-catch-finally 处理异常
在较高层的方法 a ,使用 try-catch-finally 捕获和处理所有底层方法抛出的异常。这种做法有以下优点:
集中处理:所有异常都在一个地方处理,便于管理和维护。
保证执行:即使发生异常,也可以确保 finally 块中的清理操作能够执行。
为什么要这样做
数据返回问题:如果在方法 b 中使用 try-catch 捕获并处理异常,方法 a 可能无法获得所需的数据。这是因为异常处理可能会中断正常的数据流。
异常聚合:将异常传递到高层方法,允许高层方法集中处理所有可能的异常,提高了代码的可读性和可维护性。
8. 自定义异常类
Java 中允许自定义异常(类)
- 所有异常都必须是 Throwable 的子类。
- 如果目标是写一个强制性异常类,则需要继承 Exception 类。
- 如果目标是写一个运行时异常类,则需要继承 RuntimeException 类。
- 一个异常类和其它任何类一样,包含有变量和方法。
8.1 自定义异常处理-- 支付余额不足
// 自定义异常类:余额不足
// 继承 Exception 类,该自定义异常是强制性异常,必须在编译之前,由 try-catch 捕获
public class InsufficientFundsException extends Exception
{//balanceShortage 储存当出现异常(取出钱多于余额时)所缺乏的钱private double balanceShortage;public InsufficientFundsException(double balanceShortage){this.balanceShortage= balanceShortage;} public double getBalanceShortage(){return balanceShortage;}
}
//此类模拟银行账户
public class Account {
// 区分异常类,此处的 balance 就是单纯的余额private double balance;private int cardNum;public Account (int cardNum) {this.cardNum = cardNum;}//方法:存钱public void deposit(double amount) {balance += amount;}//方法:取钱public void withdraw(double amount) throwsInsufficientFundsException {if (amount <= balance) {balance -= amount;} else {double needs = amount - balance;throw new InsufficientFundsException(needs);}}//方法:返回余额public double getBalance() {return balance;}//方法:返回卡号public int getCardNum() {return cardNum;}
}
public class BankDemo
{public static void main(String [] args){Account account = new Account(101);System.out.println("Depositing $500...");account.deposit(500.00);try{System.out.println("\nWithdrawing $100...");account.withdraw(100.00);System.out.println("\nWithdrawing $600...");account.withdraw(600.00);}catch(InsufficientFundsException e){System.out.println("Sorry, but you are short $"+ e.getBalanceShortage());e.printStackTrace();}}
}
输出为 :
Depositing $500...Withdrawing $100...Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsExceptionat CheckingAccount.withdraw(CheckingAccount.java:25)at BankDemo.main(BankDemo.java:13)
多线程
相关文章:
05 JavaSE-- 异常、IOStream、多线程、反射、Annotation、泛型、序列化
Exception 异常 异常也是对象,也有自己的体系,在这个体系中,所有异常对象的根类是 throwable 接口。异常和 error 错误是不同的概念。 错误是严重的 JVM 系统问题,一般不期待程序员去捕获、处理这些错误,同时…...
c++/c语法基础【2】
目录 1.memset 数组批量赋值 2.字符数组 编辑输入输出: 字符数组直接输入输出%s: gets! string.h 1.strlen:字符串去掉末尾\0的长度...
python 庆余年2收视率数据分析与可视化
为了对《庆余年2》的收视率进行数据分析与可视化,我们首先需要假设有一组收视率数据。由于实际数据可能无法直接获取,这里我们将使用模拟数据来演示整个过程。 以下是一个简单的步骤,展示如何使用Python(特别是pandas和matplotli…...
yolov8训练自己数据集时出现loss值为nan。
具体原因目前暂未寻找到。 解决办法 将参数amp改成False即可。 相关资料: https://zhuanlan.zhihu.com/p/165152789 https://github.com/ultralytics/ultralytics/issues/1148...
[Chapter 5]线程级并行,《计算机系统结构》,《计算机体系结构:量化研究方法》
文章目录 一、互连网络1.1 互连网络概述1.1 互连函数1.1.1 互连函数1.1.2 几种基本的互连函数1.1.2.1 恒等函数1.1.2.2 交换函数1.1.2.3 均匀洗牌函数1.1.2.4 碟式函数1.1.2.5 反位序函数1.1.2.6 移数函数1.1.2.7 PM2I函数 1.2 互连网络的结构参数与性能指标1.2.1 互连网络的结…...
首发!飞凌嵌入式FETMX6ULL-S核心板已适配OpenHarmony 4.1
近日,飞凌嵌入式在FETMX6ULL-S核心板上率先适配了OpenHarmony 4.1,这也是业内的首个应用案例,嵌入式核心板与OpenHarmony操作系统的结合与应用,将进一步推动千行百业的数智化进程。 飞凌嵌入式FETMX6ULL-S核心板基于NXP i.MX 6ULL…...
Power BI实现动态度量值
假设有一张销售数据表Sale: 报表上有一个切片器(Slicer)(下拉框样式), 当选择"第一"时,计算列[FirstSale]与列[Target]的百分比, 选择"第二"时,计算列[SecondSale]与列[Target]的百分比 选择"第三&qu…...
给大家分享一套非常棒的python机器学习课程
给大家分享一套非常棒的python机器学习课程——《AI小天才:让小学生轻松掌握机器学习》,2024年5月完结新课,提供配套的代码笔记软件包下载!学完本课程,可以轻松掌握机器学习的全面应用,复杂特征工程&#x…...
免费,Python蓝桥杯等级考试真题--第6级(含答案解析和代码)
Python蓝桥杯等级考试真题–第6级 一、 选择题 答案:D 解析:4411*4,超出范围,故答案为D。 答案:B 解析:5<8<10,故答案为B。 答案:A 解析:先比较a,然后…...
Spring Boot:SpringBoot 如何优雅地定制JSON响应数据返回
一、前言 目前微服务项目中RESTful API已经是前后端对接数据格式的标配模式了,RESTful API是一种基于REST(Representational State Transfer,表述性状态转移)原则的应用程序编程接口(Application Programming Interfac…...
c++中的constexpr 与decltype
constexpr constexpr 是 C11 引入的关键字,用于声明可以在编译时求值的常量表达式。constexpr 函数可以在编译时被计算,从而可以提高程序的性能并允许进行一些在运行时无法完成的优化。 在 C 中,constexpr 可以用于以下两种情况:…...
苹果MacOS系统使用微软远程桌面连接Windows电脑桌面详细步骤
文章目录 前言1. 测试本地局域网内远程控制1.1 Windows打开远程桌面1.2 局域网远程控制windows 2. 测试Mac公网远程控制windows2.1 在windows电脑上安装cpolar2.2 Mac公网远程windows 3. 配置公网固定TCP地址 前言 日常工作生活中,有时候会涉及到不同设备不同操作系…...
【paper】基于分布式采样的多机器人编队导航信念传播模型预测控制
Distributed Sampling-Based Model Predictive Control via Belief Propagation for Multi-Robot Formation NavigationRAL 2024.4Chao Jiang 美国 University of Wyoming 预备知识 马尔可夫随机场(Markov Random Field, MRF) 马尔可夫随机场ÿ…...
代码随想录算法训练营第二天| 977.有序数组的平方 、209.长度最小的子数组、 59.螺旋矩阵II
977. 有序数组的平方 题目链接:977. 有序数组的平方 文档讲解:代码随想录 状态:so easy 刚开始看到题目第一反应就是平方之后进行排序,数据量在 1 0 4 10^4 104,可以使用O(nlogn)的排序。但是更好的方式是使用双指针&a…...
list stream 改变list属性的值
在Java中,如果你想使用Stream API来改变List中对象的某个属性值,需要注意的是,Stream API本身设计为不可变操作,即它不直接修改原有的集合,而是产生一个新的流或集合。但是,你可以通过流操作来创建一个新的…...
绿色智能:AI机器学习在环境保护中的深度应用与实践案例
🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…...
Java高级面试精粹:问题与解答集锦(二)
Java面试问题及答案 1. 什么是Java内存模型(JMM)?它的作用是什么? 答案: Java内存模型(JMM)定义了Java虚拟机(JVM)在计算机内存中的工作方式,包括程序计数器…...
基于机器学习模型预测信用卡潜在用户(XGBoost、LightGBM和Random Forest)
基于机器学习模型预测信用卡潜在用户(XGBoost、LightGBM和Random Forest) 随着数据科学和机器学习的发展,越来越多的企业开始利用这些技术来提高运营效率。在这篇博客中,我将分享如何利用机器学习模型来预测信用卡的潜在客户。此…...
java 通过 microsoft graph 调用outlook(三)
这次会添加一个Reply接口, 并且使用6.10.0版本 直接上代码 一, POM <!-- office 365 --><dependency><groupId>com.microsoft.graph</groupId><artifactId>microsoft-graph</artifactId><version>6.1…...
QT--TCP网络通讯工具编写记录
QT–TCP网络通讯工具编写记录 文章目录 QT--TCP网络通讯工具编写记录前言演示如下:一、服务端项目文件:【1.1】server_tcp.h 服务端声明文件【1.2】thread_1.h 线程处理声明文件【1.3】main.cpp 执行源文件【1.4】server_tcp.cpp 服务端逻辑实现源文件【…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
