【Java基础】Java异常捕捉,throws/throw、finally、try、catch关键字的含义与运用
1. Java 异常处理:
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
- 比如说,你的代码少了一个分号,那么运行出来结果是提示是错 java.lang.Error;
- 如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出 java.lang.ArithmeticException 的异常。
1.1 异常分析
异常发生的原因有很多,通常包含以下几大类:
- 用户输入了非法数据。
- 要打开的文件不存在。
- 网络通信时连接中断,或者JVM内存溢出。
这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。
一要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
检查性异常:
- 最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。
- 例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常:
- 运行时异常是可能被程序员避免的异常。
- 与检查性异常相反,运行时异常可以在编译时被忽略。
错误:
- 错误不是异常,而是脱离程序员控制的问题。
- 错误在代码中通常被忽略。
- 例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
1.2 Exception 类的层次
-
所有的异常类是从 java.lang.Exception 类继承的子类。
-
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。
-
Error 用来指示运行时环境发生的错误。
例如,JVM 内存溢出。一般地,程序不会从错误中恢复。 -
异常类有两个主要的子类:IOException 类和 RuntimeException 类。
在 Java 内置类中,有大部分常用检查性和非检查性异常。
捕获异常:
- 使用 try 和 catch 关键字可以捕获异常。
- try/catch 代码块放在异常可能发生的地方。
- try/catch代码块中的代码称为保护代码。
使用 try/catch 的语法如下:
try
{// 程序代码
}catch(ExceptionName e1)
{//Catch 块
}
- Catch 语句包含要捕获异常类型的声明。
- 当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。
- 如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
下面的例子中声明有两个元素的一个数组,当代码试图访问数组的第三个元素的时候就会抛出一个异常。
import java.io.*;
public class ExcepTest{public static void main(String args[]){try{int a[] = new int[2];System.out.println("Access element three :" + a[3]);}catch(ArrayIndexOutOfBoundsException e){System.out.println("Exception thrown :" + e);}System.out.println("Out of the block");}
}
以上代码编译运行输出结果如下:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block
1.3 多重捕获块:
一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
- 多重捕获块的语法如下所示:
try{ // 程序代码 }
catch(异常类型1 异常的变量名1){ // 程序代码 }
catch(异常类型2 异常的变量名2){ // 程序代码 }
catch(异常类型2 异常的变量名2){ // 程序代码 }
上面的代码段包含了 3 个 catch块。
可以在 try 语句后面添加任意数量的 catch 块。
如果保护代码中发生异常,异常被抛给第一个 catch 块。
- 如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。
- 如果不匹配,它会被传递给第二个 catch 块。
- 直到异常被捕获或者通过所有的 catch 块。
1.4 throws/throw 关键字:
如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
- 也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
下面方法的声明抛出一个 RemoteException 异常:
import java.io.*;
public class className
{public void deposit(double amount) throws RemoteException{// Method implementationthrow new RemoteException();}//Remainder of class definition
}
!一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
例如,下面的方法声明抛出 RemoteException 和 InsufficientFundsException:
import java.io.*;
public class className
{public void withdraw(double amount) throws RemoteException,InsufficientFundsException{// Method implementation}//Remainder of class definition
}
1.5 finally关键字:
- finally 关键字用来创建在 try 代码块后面执行的代码块。
- 无论是否发生异常,finally 代码块中的代码总会被执行。=
- 在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
finally 代码块出现在 catch 代码块最后,语法如下:
try{ // 程序代码 }
catch(异常类型1 异常的变量名1){ // 程序代码 }
catch(异常类型2 异常的变量名2){ // 程序代码 }
finally{ // 程序代码 }
注意下面事项:
-
catch 不能独立于 try 存在。
-
在 try/catch 后面添加 finally 块并非强制性要求的。
-
try 代码后不能既没 catch 块也没 finally 块。
-
try, catch, finally 块之间不能添加任何代码。
1.6 声明自定义异常:
在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
-
所有异常都必须是 Throwable 的子类。
-
如果希望写一个检查性异常类,则需要继承 Exception 类。
-
如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
可以像下面这样定义自己的异常类:
class MyException extends Exception{ }
- 只继承Exception 类来创建的异常类是检查性异常类。
下面的 InsufficientFundsException 类是用户定义的异常类,它继承自 Exception。
一个异常类和其它任何类一样,包含有变量和方法。
以下实例是一个银行账户的模拟,通过银行卡的号码完成识别,可以进行存钱和取钱的操作。
import java.io.*;
//自定义异常类,继承Exception类
public class InsufficientFundsException extends Exception
{//此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱private double amount;public InsufficientFundsException(double amount){this.amount = amount;}public double getAmount(){return amount;}
}
为了展示如何使用我们自定义的异常类,
在下面的 CheckingAccount 类中包含一个 withdraw() 方法抛出一个 InsufficientFundsException 异常。
import java.io.*;
//此类模拟银行账户
public class CheckingAccount
{//balance为余额,number为卡号private double balance;private int number;public CheckingAccount(int number){this.number = number;}//方法:存钱public void deposit(double amount){balance += amount;}//方法:取钱public void withdraw(double amount) throws InsufficientFundsException{if(amount <= balance){balance -= amount;}else{double needs = amount - balance;throw new InsufficientFundsException(needs);}}//方法:返回余额public double getBalance(){return balance;}//方法:返回卡号public int getNumber(){return number;}
}
下面的 BankDemo 程序示范了如何调用 CheckingAccount 类的 deposit() 和 withdraw() 方法。
public class BankDemo
{public static void main(String [] args){CheckingAccount c = new CheckingAccount(101);System.out.println("Depositing $500...");c.deposit(500.00);try{System.out.println("\nWithdrawing $100...");c.withdraw(100.00);System.out.println("\nWithdrawing $600...");c.withdraw(600.00);}catch(InsufficientFundsException e){System.out.println("Sorry, but you are short $" + e.getAmount());e.printStackTrace();}}
}
编译上面三个文件,并运行程序 BankDemo,得到结果如下所示:
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)
1.7 通用异常:
在Java中定义了两种类型的异常和错误。
-
JVM(Java虚拟机) 异常:
- 由 JVM 抛出的异常或错误。
- 例如:NullPointerException 类,ArrayIndexOutOfBoundsException 类,ClassCastException 类。
-
程序级异常:
- 由程序或者API程序抛出的异常。
- 例如 IllegalArgumentException 类,IllegalStateException 类。
2. ❤️Java基础专栏 - 前篇回顾
- 认识Java,Java程序的生命周期,运行Java程序
- Java数据类型阐述、基本数据类型的占用和范围、二进制的讲述
- 8种基本数据类型的分析、数据类型转换规则、转义字符的列举
- 五种运算符的说明(&&、||、>=、>、<=、<)、4种控制语句(if、for、while、dowhile)、输入和输出说明
- 方法的概念、方法的调用、方法重载、构造方法的创建
- 全方面带你了解Java里的日期与时间内容,介绍 Calendar、GregorianCalendar、Date类
- 正则表达式的使用与常用类分享
- Stream流、文件File相关操作,IO的含义与运用
3. 💕👉 其他好文推荐
- 还不了解Git分布式版本控制器?本文将带你全面了解并掌握
- 带你认识Maven的依赖、继承和聚合都是什么!有什么用?
- 2-3树思想与红黑树的实现与基本原理
- !全网最全! ElasticSearch8.7 搭配 SpringDataElasticSearch5.1 的使用
- 全面深入Java GC!!带你完全了解 GC垃圾回收机制!!
- 全面了解Java的内存模型(JMM)!详细清晰!
- 在JVM中,类是如何被加载的呢?本篇文章就带你认识类加载的一套流程!
- 带你了解Go语言的判断语句、切片和映射表!!
- (Java并发编程—JUC)带你重新认识进程与线程!!让你深层次了解线程运行的睡眠与打断!!
相关文章:
【Java基础】Java异常捕捉,throws/throw、finally、try、catch关键字的含义与运用
1. Java 异常处理: 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。 比如说,你的代码少了一个分号,那么运行出来结果是提示是错 java.lang.Error;如果你用System.out.p…...
Android Studio 安装配置(个人笔记)
Android studio安装的前提是必须保证安装了jdk1.8版本以上 一、查看是否安装jdk cmd打开命令行,输入java -version 最后是一个关键点 输入 javac ,看看有没有相关信息 没有就下载jdk Android studio安装的前提是必须保证安装了jdk1.8版本以上 可以到…...
计算机网络——数据链路层-介质访问控制
一、介质访问控制方法 在局域网中, 介质访问控制(medium access control)简称MAC,也就是信道访问控制方法,可以 简单的把它理解为如何控制网络节点何时发送数据、如何传输数据以及怎样在介质上接收数据, 是解决当局域网中共用信道的使用产生竞…...
pytest日志显示
在 pytest 中,可以通过 钩子函数 和 配置文件 pytest.ini 配置日志的显示方式,实现对日志的灵活控制。以下是常用实现方式及配置说明。 方式一:使用 conftest.py 钩子函数自定义日志显示 通过 conftest.py 文件中的钩子函数,实现…...
【信息系统项目管理师】第15章:项目风险管理过程详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 一、规划风险管理1、输入2、工具与技术3、输出二、识别风险1、输入2、工具与技术3、输出三、实施定性风险分析1、输入2、工具与技术3、输出四、实施定量风险分析1、输入2、工具与技术3、输出五、规划风险应对1、…...
Diffusers 使用 LoRA
使用diffusers 加载 LoRA,实现文生图功能。摘自 diffusers文档。 模型可以根据名称去modelscope找对应资源下载。使用的时候需要替换成具体路径。虽然modelscope和diffusers都使用了模型id,但是并不能通用。 不同的LoRA对应了不同的“trigger” words&am…...
云安全博客阅读(二)
2024-05-30 Cloudflare acquires BastionZero to extend Zero Trust access to IT infrastructure IT 基础设施的零信任 不同于应用安全,基础设置的安全的防护紧急程度更高,基础设施的安全防护没有统一的方案IT基础设施安全的场景多样,如se…...
SpringCloud系列教程:微服务的未来(六)docker教程快速入门、常用命令
对于开发人员和运维工程师而言,掌握 Docker 的基本概念和常用命令是必不可少的。本篇文章将带你快速入门 Docker,并介绍一些最常用的命令,帮助你更高效地进行开发、测试和部署。 目录 前言 快速入门 docker安装 配置镜像加速 部署Mysql …...
Vue 快速入门:开启前端新征程
在当今的 Web 开发领域,Vue.js 作为一款极具人气的 JavaScript 前端框架,正被广泛应用于各类项目之中。它以简洁的语法、高效的数据绑定机制以及强大的组件化开发模式,为开发者们带来了前所未有的开发体验。如果你渴望踏入前端开发的精彩世界…...
UVM:uvm_component methods configure
topic UVM component base class uvm_config_db 建议使用uvm_config_db代替uvm_resource_db uvm factory sv interface 建议:uvm_config_db 以下了解 建议打印error...
LLM 训练中存储哪些矩阵:权重矩阵,梯度矩阵,优化器状态
LLM 训练中存储哪些矩阵 目录 LLM 训练中存储哪些矩阵深度学习中梯度和优化器是什么在 LLM 训练中通常会存储以下矩阵: 权重矩阵:这是模型的核心组成部分。例如在基于 Transformer 架构的 LLM 中,每一层的多头注意力机制和前馈神经网络都会有相应的权重矩阵。以 BERT 模型为…...
大模型思维链推理的进展、前沿和未来分析
大模型思维链推理的综述:进展、前沿和未来 "Chain of Thought Reasoning: A State-of-the-Art Analysis, Exploring New Horizons and Predicting Future Directions." 思维链推理的综述:进展、前沿和未来 摘要:思维链推理&#…...
NLP 技术的突破与未来:从词嵌入到 Transformer
在过去的十年中,自然语言处理(NLP)经历了深刻的技术变革。从早期的统计方法到深度学习的应用,再到如今Transformer架构的普及,NLP 的发展不仅提高了模型的性能,还扩展了其在不同领域中的应用边界。 1. 词嵌…...
嵌入式中QT实现文本与线程控制方法
第一:利用QT进行文件读写实现 利用QT进行读写文本的时候进行读写,读取MP3歌词的文本,对这个文件进行读写操作。 实例代码,利用Qfile,对文件进行读写。 //读取对应文件文件,头文件的实现。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #incl…...
云备份项目--服务端编写
文章目录 7. 数据管理模块7.1 如何设计7.2 完整的类 8. 热点管理8.1 如何设计8.2 完整的类 9. 业务处理模块9.1 如何设计9.2 完整的类9.3 测试9.3.1 测试展示功能 完整的代码–gitee链接 7. 数据管理模块 TODO: 读写锁?普通锁? 7.1 如何设计 需要管理…...
Node.js——fs(文件系统)模块
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
SAP BC 同服务器不同client之间的传输SCC1
源配置client不需要释放 登录目标client SCC1...
CentOS: RPM安装、YUM安装、编译安装(详细解释+实例分析!!!)
目录 1.什么是RPM 1.1 RPM软件包命名格式 1.2RPM功能 1.3查询已安装的软件:rpm -q 查询已安装软件的信息 1.4 挂载:使用硬件(光驱 硬盘 u盘等)的方法(重点!!!) 1…...
linux音视频采集技术: v4l2
简介 在 Linux 系统中,视频设备的支持和管理离不开 V4L2(Video for Linux 2)。作为 Linux 内核的一部分,V4L2 提供了一套统一的接口,允许开发者与视频设备(如摄像头、视频采集卡等)进行交互。无…...
MySQL使用navicat新增触发器
找到要新增触发器的表,然后点击设计,找到触发器标签。 根据实际需要,填写相关内容,操作完毕,点击保存按钮。 在右侧的预览界面,可以看到新生成的触发器脚本...
在Windows系统安装Docker
在 Windows 上安装 Docker,核心是安装 Docker Desktop(官方 GUI 工具),并启用 WSL 2(推荐,性能最好)。以下是最新、最稳的完整教程(Win10/Win11 通用)。 一、先检查系统与…...
Fish Speech 1.5惊艳效果:中英混合文本语音合成真实案例分享
Fish Speech 1.5惊艳效果:中英混合文本语音合成真实案例分享 1. 语音合成技术的新突破 今天要给大家分享一个让我眼前一亮的语音合成技术——Fish Speech 1.5。这不是那种机械感十足的普通TTS,而是一个真正能说"人话"的智能语音合成模型。 …...
新手必看!立知lychee-rerank-mm部署教程:从安装到调用全流程
新手必看!立知lychee-rerank-mm部署教程:从安装到调用全流程 1. 什么是lychee-rerank-mm? lychee-rerank-mm是一个轻量级多模态重排序工具,它能帮你解决一个常见但棘手的问题:当系统返回一堆搜索结果后,如…...
生存分析实战:Harrell’s C-index 评估模型预测能力的核心原理与应用
1. 为什么需要Harrell’s C-index? 在医学研究和生物统计领域,我们经常需要评估患者的生存时间。比如预测癌症患者的五年生存率,或者评估某种治疗方案对延长患者生命的效果。这时候就会用到生存分析模型。但问题来了:你怎么知道这…...
3分钟搞定AI写作神器:KoboldAI本地部署终极指南 [特殊字符]
3分钟搞定AI写作神器:KoboldAI本地部署终极指南 🚀 【免费下载链接】KoboldAI-Client For GGUF support, see KoboldCPP: https://github.com/LostRuins/koboldcpp 项目地址: https://gitcode.com/gh_mirrors/ko/KoboldAI-Client 还在为AI写作工具…...
如何快速解决电脑卡顿问题:Mem Reduct内存管理实用指南
如何快速解决电脑卡顿问题:Mem Reduct内存管理实用指南 【免费下载链接】memreduct Lightweight real-time memory management application to monitor and clean system memory on your computer. 项目地址: https://gitcode.com/gh_mirrors/me/memreduct 电…...
Go语言中的测试与基准测试:从单元测试到性能优化
Go语言中的测试与基准测试:从单元测试到性能优化 1. 测试的重要性 在软件开发中,测试是确保代码质量和可靠性的关键环节。Go语言内置了强大的测试框架,使得编写和运行测试变得简单高效。本文将详细介绍Go语言中的测试方法,从基础…...
MATLAB图像分割实战:从基础阈值到分水岭算法的进阶指南
1. 图像分割基础与MATLAB环境准备 图像分割是计算机视觉中的基础任务,简单来说就是把图像中我们感兴趣的部分"抠"出来。想象一下你在玩拼图游戏,图像分割就是帮你把拼图的每一块单独取出来的过程。在MATLAB里做图像分割,就像拥有了…...
Linux I/O 演进史:从管道到零拷贝,一篇串起个服务端核心原语于
前言 在使用 kubectl get $KIND -o yaml 查看 k8s 资源时,输出结果中包含大量由集群自动生成的元数据(如 managedFields、resourceVersion、uid 等)。这些信息在实际复用 yaml 清单时需要手动清理,增加了额外的工作量。 使用 kube…...
为什么92%的AI原生应用无法精准归因故障?曝光3个被忽视的OpenTelemetry SDK陷阱、2个LLM Token级Span拆分反模式
第一章:AI原生软件研发链路追踪系统搭建 2026奇点智能技术大会(https://ml-summit.org) AI原生软件的研发过程高度依赖模型版本、数据集快照、训练参数、推理服务部署状态及用户反馈信号的强关联性。传统APM工具难以刻画从Prompt工程→微调训练→RAG索引更新→LLM网…...
