当前位置: 首页 > news >正文

异常的处理

什么是异常

java中不正常的行为称为异常,不同类型的异常都有对应的类描述。

异常的种类

异常体系结构

这只是异常体系的一部分,异常的种类有很多。只需要关注几个重要的类。
Throwable :是异常体系的顶层类,派生出Error,Exception两个重要子类。
Error:表示错误,指发生Java虚拟机无法解决的严重问题,如JVM的内部错误,资源耗尽等。
 典型代表: StackOverflowError OutOfMemoryError
Exception:表示产生的异常,可通过代码处理,使程序继续运行。
运行异常(非受查异常)

RuntimeException及其子类表示运行异常,表示在程序运行期间发生的异常。

编译异常(受查异常)

Exception的子类除了RuntimeException及其子类都是编译异常的类, 表示在编译期间发生的异常

异常的关键字

抛出异常
throw
throw  new   XXXException(“异常产生的原因”) );//定义异常类型,将异常对象抛给方法调用者,如果调用者不处理最终就是JVM处理
//一个获取数组中任意位置元素的方法
public static int getElement(int[] array, int index){
if(null == array){
throw new NullPointerException("传递的数组为null");
}
if(index < 0 || index >= array.length){
throw new ArrayIndexOutOfBoundsException("传递的数组下标越界");
}
return array[index];
}
public static void main(String[] args) {
int[] array = {1,2,3};
getElement(array, 3);
}

1.抛出的只能是Exception类及其子类的异常(Error的异常会导致计算机程序崩溃,jvm也处理不了,不用抛给他);

2.如果是编译时异常,得及时处理,如果是运行时异常不用处理,交给JVM处理;

3.throw只能写在方法体内部;

4.发生异常,异常后面的代码无法执行。

捕获异常  

捕获异常,对异常的具体处理;

thows  

作用:

声明异常, 处在方法参数列表之后,当方法中抛出编译时异常,但不想立马处理该异常,就可以借助throws提醒方法的调用者来处理 。即当前不处理异常,让方法调用者处理。

编译异常:

这类异常要么在方法中使用 try-catch 块捕获处理,要么通过 throws 关键字声明抛出。它们通常是外部因素引起的异常,比如文件未找到、网络连接失败等。

运行异常:

继承自 RuntimeException 的异常属于运行时异常。虽然也可以使用 throws 来声明,但不是必需的。常见的例子包括 NullPointerException 

语法格式:
修饰符  返回值类型     方法名 ( 参数列表 )      throws      异常类型 1 ,异常类型 2 ...{ }
注意:
1. throws 必须跟在方法的参数列表之后;
2. 方法内部如果抛出了多个异常, throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多
个异常类型,具有父子关系,直接声明父类即可;
3 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用 throws 抛出。
thow和thows区别
特性throwthrows
用途主动抛出一个具体的异常对象声明方法可能抛出的异常类型
位置方法体内使用方法签名部分使用
语法throw 异常对象;throws 对象1,对象2...
数量一次只能抛出一个异常可以声明多个异常类型
处理必须立即处理或向上传递只是声明,不实际抛出异常
try catch
throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行处理,就需要 try-catch catch捕获try中产生的异常,如果没有相应异常的类型捕获,就继续向上抛出,直到被JVM收到终止程序。
语法格式:
try{
// 将可能发生异常 的代码放在try{}的代码块里
return ;  //执行完finally里的代码才会return
}catch(要捕获的异常类型 e){
//处理异常 的代码放这里
}catch(异常类型 e){
//可以多定义几个类型的变量进行捕获
}finally{//finally里的代码一定会被执行,确保一些资源被关闭
  
}
注意:
1.   try 中的代码可能会抛出异常,也可能不会;
2. try 块内抛出异常位置之后的代码将不会被执行;
3.  如果抛出异常类型与 catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到JVM 收到后中断程序 ---- 异常是按照类型来捕获的;
4. try 中可能会抛出多个不同的异常对象,则必须用多个 catch 来捕获 ---- 即多种异常,多次捕获,
如果多个异常的处理方式是完全相同 , 也可以写成这样:
catch   ( ArrayIndexOutOfBoundsException | NullPointerException e ) {};
5. 如果异常之间具有父子关系,一定是子类异常在前 catch ,父类异常在后 catch ,否则语法错误。
//读取配置文件,如果配置文件名字不是指定名字,抛出异常,调用者进行异常处理
public class Config {
File file;
public void openConfig(String filename) throws FileNotFoundException{
if(!filename.equals("config.ini")){
throw new FileNotFoundException("配置文件名字不对");
}
// 打开文件
}
public void readConfig(){
}
public static void main(String[] args) {
Config config = new Config();
try {
config.openConfig("config.txt");
System.out.println("文件打开成功");
} catch (IOException e) {
// 异常的处理方式
//System.out.println(e.getMessage()); // 只打印异常信息
//System.out.println(e); // 打印异常类型:异常信息
e.printStackTrace(); // 打印信息最全面
}
// 一旦异常被捕获处理了,后面的代码继续执行
System.out.println("异常如果被处理了,这里的代码也可以执行");
}
}

关于调用栈:方法之间存在相互调用的关系,这个关系用调用栈来描述。JVM中有一空间专门存储方法之间的调用关系,叫虚拟机栈,当代码出现异常,可以用e.printStackTrace()来查看出现的异常。
finally

finally{} 代码块里的代码一定会被执行。写程序时有些代码不论是否发生异常,都需要执行,如程序中打开的资源:网络连接,数据库连接,IO流等。在程序正常或者异常退出时,都要对资源进行回收。异常会引发程序的跳转,可能有些语句执行不到,就需要用到finally。

流的自动关闭机制

在 Java 7 引入的 try-with-resources 语句中,当在try() 中开启的流(或其他实现了AutoCloseable接口 的资源,如InputStream,OutputStream等)出现异常时,系统会自动关闭资源。

try (InputStream is = new FileInputStream("file.txt")) {// 使用流
}catch(){//异常处理};
-------------------------------------// 编译器生成的等效代码,也是在finally中关闭资源
InputStream is = new FileInputStream("file.txt");
try {// 使用流
} finally {if (is != null) {is.close();  // 自动调用close()}
}
异常处理流程总结
如果本方法中没有合适的处理异常的方式 , 就会沿着调用栈向上传递
1.程序先执行 try 中的代码;
2.如果 try 中的代码出现异常 , 就会结束 try 中的代码 , 看和 catch 中的异常类型是否匹配;
3.如果找到匹配的异常类型 , 就会执行 catch 中的代码,如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者;
4.无论是否找到匹配的异常类型 , finally 中的代码都会被执行到 ( 在该方法结束之前执行 );
5.如果上层调用者也没有处理的了异常 , 就继续向上传递, 一直到 main 方法也没有合适的代码处理异常 , 就会交给 JVM 来进行处理 , 此时程序就会异常终止。

自定义异常

java中虽然定义的异常类型很多,但没有与实际情况符合的异常时,可以自定义异常类,让其继承Exception或RuntimeException 。

继承Exception默认是编译时异常,继承RuntimeException默认是运行时异常。

//实现一个用户登陆功能
public class LogIn {
private String userName = "admin";
private String password = "123456";
public static void loginInfo(String userName, String password) {
if (!userName.equals(userName)) {
}
if (!password.equals(password)) {
}
System.out.println("登陆成功");
}
public static void main(String[] args) {
loginInfo("admin", "123456");
}
}
//此时我们在处理用户名密码错误的时候可能就需要抛出两种异常. 
我们可以基于已有的异常类进行扩展(继承), 创建
和我们业务相关的异常类.
//具体方式:
1. 自定义异常类,然后继承自Exception 或者 RunTimeException
2. 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因
class UserNameException extends Exception {
public UserNameException(String message) {
super(message);
}
}
class PasswordException extends Exception {
public PasswordException(String message) {
super(message);
}
}
//将代码改成
public class LogIn {
private String userName = "admin";
private String password = "123456";
public static void loginInfo(String userName, String password)
throws UserNameException,PasswordException{
if (!userName.equals(userName)) {
throw new UserNameException("用户名错误!");
}
if (!password.equals(password)) {
throw new PasswordException("用户名错误!");
}
System.out.println("登陆成功");
}
public static void main(String[] args) {
try {
loginInfo("admin", "123456");
} catch (UserNameException e) {
e.printStackTrace();
} catch (PasswordException e) {
e.printStackTrace();
}
}
}

http://www.lqws.cn/news/457597.html

相关文章:

  • 云计算与5G:如何利用5G网络优化云平台的性能
  • 芋道源码 - 添加反向代理, 通过公网域名访问静态资源图片
  • 【国产AI服务器】全国产PCIE5.0交换板,替代博通89104/89144,支持海光、龙芯等平台
  • 日常运维问题汇总-16
  • 西门子S7通信协议抓包分析应用
  • Tomcat项目本地部署(Servlet为例)
  • 详解Redis的热点key问题
  • linux线程同步
  • Rust 项目文档生成之旅:cargo doc
  • 字符编码(UTF-8,16,32 和GBK和ASCLL码)
  • AI Agent开发与安全
  • 数据结构-顺序表-求基数乘积
  • 《Go语言圣经》类型断言应用:高效类型判断
  • I排序算法.go
  • 如何轻松将照片从 iPhone 传输到 Android?
  • 【八股消消乐】Elasticsearch优化—检索Labubu
  • NumPy玩转数据科学
  • Java 集合框架底层数据结构实现深度解析
  • 高效打印 PDF 文档:基础操作与自动打印(含C# .NET方案)
  • tkinter 的 grid() 布局管理器学习指南
  • Matter协议开发者指南:使用Matter SDK构建智能家居应用
  • 礼让行人:深圳 vs 上海
  • 性能测试-jmeter实战3
  • GitHub Copilot 配置快捷键
  • NestJS中实现动态Cron任务管理
  • 榕壹云婚恋相亲系统:ThinkPHP+UniApp打造高效婚配平台
  • Unity3D仿星露谷物语开发66之NPC存档
  • 如何使用postman做接口自动化测试?
  • python高校工作室管理系统
  • 基于存储过程的MySQL自动化DDL同步系统设计