2022-07-29 第4组 蒋萍 Java常见异常及处理
“乐观才是常态”
Java异常及异常处理
异常是一种特殊的对象,类型为java.lang.Exception或其子类
当一个程序抛出异常时,抛异常后面的语句不再执行,类似于return的功能,
终止方法的执行
Java异常处理通过5个关键字来实现:try
、catch
、finally
、throw
、throws
-
捕获异常:
-
try:执行可能产生异常的代码;
-
catch:捕获异常;
-
finally:无论是否发生异常,代码总能执行;
-
-
声明异常:
- throws:声明方法可能要抛出的各种异常;
- throw:手动抛出异常;
1、try-catch 块捕获异常
1.1 情况1:正常
public void method(){
try{
// 代码段(此处不会产生异常)
}catch (Expection ex){ //异常对象ex
// 对异常进行处理的代码段
}
// 代码块
}
/* catch 是发生异常时才进入,
当正常时会跳过catch直接执行catch外的代码
*/
1.2 情况2:出现异常
public void method(){
try{
// 代码段1
// 代码段2(此处产生异常)
// 代码段3
}catch (Expection ex){ //异常对象ex
// 对异常进行处理的代码段
}
// 代码块
}
printStackTrace() //打印异常堆栈信息;
- try ( 发生异常 )——> 产生异常对象——> 异常类型匹配(进入catch块)——> catch(程序继续执行)——> try-catch块后的代码
1.3 情况3:出现异常,但异常类型不匹配
public void method(){
try{
// 代码段1
// 代码段2(此处产生异常)
// 代码段3
}catch (Expection ex){ //异常对象ex
// 对异常进行处理的代码段4
}
// 代码块5
}
- try(发生异常)——> 产生异常对象——> 异常类型不匹配——> (程序中断运行)
总结:
try{
//
}catch(异常Exception 或Exception的子类){
//
}
1、无异常。执行try-catch后的代码
2、有异常。而且和catch 抓住的异常匹配,执行try--> catch里面的代码且catch后面的代码也会执行
3、有异常。try--> 异常和catch(异常)不匹配,直接在catch这里中断,catch后面的代码页不会执行
-
当程序出现异常,printStackTrace() 的堆栈跟踪功能显示出程序运行到当前类的执行流程,我们看到异常堆栈信息,从下往上看提示内容,找错从上往下找
-
getMessage: 获取异常的字符串提示信息(但并不是所有的异常都有提醒!),是printStackTrace()输出信息的一部分
2、try-catch-finally
在 tyr-catch 块后加入finnally
- 是否发生异常都会执行;
- 不执行的唯一情况:!!!!!try 块(有异常) ——> catch块(System.exit(1)),中断程序退出jvm,此时finally块不执行
3、存在return的try-catch-finally块
public void method(){
try{
// 代码段1
// 代码段2(此处产生异常)
}catch (Expection ex){ //异常对象ex
// 对异常进行处理的代码段3
return;
}finally{
// 代码块4
}
}
此时,代码块4会执行吗????
会!!!!
那要是把return 加在try块里,finally会执行吗???
会!!!
问题:
try-catch块中存在return语句,是否还执行finally块,如果执行,说出执行顺序?
要执行,先try-catch块,然后执行finally,再跳到return执行,结束方法。
4、多重catch块
引发多种类型异常时
- 排列catch 语句顺序:先子类后父类;
- 发生异常时会按顺序逐个匹配;
- 只执行第一个和异常类型匹配的catch语句
try{
// 代码段
} catch (IOException exp ){
System.out.println("捕获IO异常"+exp);
}catch (Exception exp2){// 尽量精确捕捉异常
// 代码块
}finally {
System.out.println("管你捕获到异不异常,我都执行" );
}
注意:!!try必须要写
try不能单独出现,要么try-catch,要么try-finally,要么就try-catch-finally
5、声明异常
- 如果在一个方法中抛出了异常,如何通知调用者?
throws 声明某个方法可能抛出的各种异常,多个异常用逗号隔开
-
(我处理不了这个炸弹,你试试~) ——>
-
方式一: (炸弹到我这里)——> 调用者处理异常
-
方式二:(啊啊啊,我也处理不了~)——> 调用者继续声明异常
-
到最后,不解决的话,到main() 方法声明的异常由JVM处理了(害,还得靠我)
-
发生异常,要么告诉别人(throws)要么处理(throw)
- 抛出指定异常信息:
throw new Except("我是你指定的异常信息")
一旦出现throw, 一定要有throws 或者 try-catch处理,要么继续throws!!!
6、throw和throws
-
throw:生成并抛出异常;位于方法体内部;可单独语句使用;抛出异常对象只能是一个;
-
throws:声明方法内抛出了异常;必须跟在方法参数列表后面;声明抛出异常可以是多个;
7、异常体系结构
7.1 Error
靠程序本身无法恢复的严重错误。
7.2 Exception
由Java应用程序抛出和处理的非常严重的错误。
-
Checked 检查异常——> 编译时就不通过, 一定要处理:要么try-catch要么throws声明
比如 IoException,ClassNotFoundException 等
-
RuntimeException 运行时异常——> 编译时不报错,运行时异常,不要求一定要处理
NullPointException,ArithmeticException 等
8、自定义异常
当jdk中的异常类型不能满足所需时可以使用;
8.1 步骤
1、定义异常类——> 继承Throwable类、继承Exception或RuntiomException
2、编写构造方法,继承父类实现(super.)
3、实例化自定义异常对象
4、使用 throw 抛出
举例:
9、异常处理原则
异常处理与性能;
异常只能用于非正常情况;
不要将过于庞大的代码块放再try中;
在catch中指定具体的异常类型;
需要对捕获的异常做处理;
一些补充
- 在一个有返回值的方法中,如果有条件分支,一定要保证每种情况下都有返回值,哪怕是抛异常。开发中,大部分情况下使用的都是运行期异常!!!
- 如果一个方法没有捕获一个编译期异常,该方法必须使用throws来声明throws并不是真正的解决了异常,只是把异常抛给了下一级调用者。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库