Java异常处理
异常概述与异常体系结构
异常可以分为两类:
Error:Java虚拟机无法解决的严重问题:JVM系统内部错误,资源耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性代码处理
main(args);//栈溢出
Integer[] arr=new Integer[1024*1024*1024];//堆溢出
Exception:其他一般性问题,可以编写针对代码处理。如空指针访问、试图读写不存在的文件、网络连接中断、数组越界一般异常处理只针对
包括编译时异常(受检异常)、运行时异常(非受检异常)
异常的抓抛模型:
过程一:抛:程序正常执行过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出。一旦抛出对象后,其后的代码就不再执行
过程二:抓:可以理解为异常处理方式:①try-catch-finally ②throws
异常对象的产生:
- 系统自动生成
- 用户手动产生(throws)
常见异常
编译时异常
如:
IOException:输入输出流异常
ClassnotFoundException:找不到文件异常
编译时异常编译器会直接报错
运行时异常
NullPointerException:空指针异常
int[] arr=null;
System.out.println(arr[3]);
ArrayIndexOutOfBoundsException:数组角标越界
ClassCastException:类型转换错误
Object obj=new Data();
String str=(String)obj;
NumberFormatException:数字类型转换异常
String str="123";
str="abc";
int num=Integer.parseInt(str);
InputMismatchException:输入匹配异常
本应输入int却输入了字符串时
Scanner scanner=new Scanner(System.in);
int score=scanner.nextInt();
System.out.println(score);
ArithmeticException:算术异常,如除0
异常处理机制:try-catch-finally
结构
try{
//可能出现异常的代码
}catch(异常类型1 变量名1){
//处理异常的方式
}catch(异常类型2 变量名2){
//处理异常的方式
}catch(异常类型2 变量名2){
//处理异常的方式
}
....
finally{
//一定会执行的代码
}
使用说明
举例:
public void test() {
String str="223";
str="abc";
try {
int num=Integer.parseInt(str);
System.out.println("正常执行了");
}catch (NumberFormatException e) {
System.out.println("数值转换异常");
e.getMessage();//得到抛出的异常信息 即"异常"
e.printStackTrace();
}catch(Exception e) {
System.out.println("异常");
}
}
- finally是可选的
- 使用try将可能出现异常的代码包装起来,使用中一旦出现异常,就会生成一个异常的类型,去catch中去匹配,一旦匹配到某个catch,则执行对应catch中的代码,进行异常处理,没有finally时跳出try catch结构,继续执行其后的代码
- catch中的异常类型,如果没有子父类关系,则谁声明在上谁先执行。如果满足子父类关系,要求子类执行在父类前面,否则报错
- 常用的异常对象处理方式
e.getMessage();//打印抛出的异常信息
e.printStackTrace();//打印堆栈信息,更常用
- try结构中声明的变量,出了try结构后不能再被调用
- 使用try catch结构处理编译时异常,是得程序在编译时就不再报错,但是运行时仍然可能报错,相当于将编译时异常延迟到运行时出现
- 开发中由于运行时异常比较常见,所以我们通常不针对运行时异常编写try-catch-finally。针对编译时异常,一定要考虑try catch
finally
- finally是可行的
- finally中声明的是一定会被执行的代码,即使catch中又出现异常了,try中有异常,有return语句等情况
- 像数据库连接、输入输出流、网络编程Socket等资源、JVM是不能自动回收的,我们需要自己手动进行释放。此时的资源释放,就需要声明在finally中
异常处理机制2:throws
结构:
throws:异常类型
使用
- throws+异常类型写在方法声明处。指明可能抛出的异常类型
一旦方法执行时出现满足写明的异常类型时,就会被抛出,异常代码后续的代码就不再执行
- try catch真正的处理了异常
throws只是把异常抛给方法的调用者,并没有真正的处理异常
- 开发中如何选择try-catch还是throws
- 如果父类中被重写的方法没有throws方式处理异常,子类也不能使用throws;如果子类重写的方法有异常,只能用try-catch(多线程有应用)
- 执行的方法中先后又调用了另外几个方法,这几个方法递进关系执行时,建议这几个方法使用throws,执行的方法可以使用try-catch
重写方法异常抛出
子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型。父类没有抛异常,子类也不能
手动抛出异常
throw new RuntimeException("你输入的数据非法!");//运行时异常,可以不处理
throw new Exception("你输入的数据非法!");//包含编译时异常,必须处理,可以在方法声明出加throws对应异常对象处理
如何自定义异常
//1.继承于现有的异常结构,RuntimeException,Exception
public class MyException extends RuntimeException{
//2.提供全局常量 serialVersionUID 版本序列号 标识类
static final long serialVersionUID = -7034897190745766939L;
//3.提供重载构造器
public MyException() {
}
public MyException(String msg) {
super(msg);
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战