异常语法详解

异常语法详解

  • 一:异常的分类:
  • 二:异常的处理
    • 1:异常的抛出:throw
    • 2:异常的声明:throws
    • 3:try-catch捕获并处理异常
  • 三:finally关键字
  • 四:自定义异常类:

一:异常的分类:

1:编译时异常:在程序编译期间发生的异常,称为编译时异常,也称受查异常。
2:运行时异常:在程序执行期间发生的异常,称为运行时异常,也称非受查异常。RunTimeException以及子类构成的异常,都称为运行时异常。
编译时出现的语法错误,不能称为异常。比如拼写错误关键字。

二:异常的处理

1:异常的抛出:throw

在Java中,使用throw将异常抛出,将错误信息告知给调用者。
注意:
1:throw 必须写在方法的内部
2:抛出的对象必须是Exception或者是Exception的子类对象
3:如果抛出的是RunTimeException,或者是RunTimeException的子类,则可以不处理,直接交给JVM来处理
4:异常一旦抛出,其后的代码就不会再执行 。

举例说明:

public class Test {public static void fun(int[] array){if(array==null){throw new NullPointerException();//throw关键字来抛出运行时异常System.out.println("异常");//异常抛出,该句代码不会再执行}}public static void main(String[] args) {//此时fun()的调用者main()对异常也没有处理,将交给JVM来处理int[] array=null;fun(array);}
}

5:如果抛出的是编译时异常,用户必须处理,否则无法通过编译。

public class Test {public static void fun(int[] array) throws CloneNotSupportedException {if(array==null){throw new CloneNotSupportedException();//受查异常,必须处理,但可以通过throws关键字声明,交给调用者处理}}public static void main(String[] args) throws CloneNotSupportedException{int[] array=null;fun(array);//该调用者main()也没有处理,但也通过throws声明了,此时将交给JVM来处理}
}

2:异常的声明:throws

处在方法声明时的参数列表之后,当方法中抛出已换成那个时,用户不想处理该异常,就可以通过throws将异常抛给方法的调用者来处理。
当前方法不处理,交给该方法的调用者来处异常
注意:
1:throws必须跟在方法的参数列表之后
2:声明的异常必须是Exception,或者是Exception的子类;
3:方法的内部如果出现了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出的多个异常类型具有父子关系,直接声明父类即可。
4:调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用Throws抛出。

public class Test {public static void fun(int[] array) throws CloneNotSupportedException {if(array==null){throw new CloneNotSupportedException();//受查异常,必须处理,但可以通过throws关键字声明,交给调用者处理}}public static void main(String[] args) throws CloneNotSupportedException{int[] array=null;fun(array);//该调用者main()也没有处理,但也通过throws声明了,此时将交给JVM来处理}
}

3:try-catch捕获并处理异常

throws并没有对异常进行真正的处理,而是将异常报告给抛出异常方法的调用者,由调用者来处理,如果想要对异常进行处理,就需要try-catch。
注意:
1:try块内抛出异常位置后的代码即将不会被执行;
2:如果抛出的异常与catch时的异常不匹配,即异常不会被成功捕获,也不会被处理,继续往外抛,直到JVM来处理

public class Test {public static void fun(int[] array){try{System.out.println(array[10]);//抛出的是数组越界异常System.out.println(10/0);//抛出的是算数异常}catch (ArithmeticException e){//没有处理数组越界异常,将交给该方法的调用者来处理//但该方法的调用者main()并没有处理,将交给JVM来处理e.printStackTrace();System.out.println("算数异常");}}public static void main(String[] args) {int[] array={1,2,3,4};fun(array);}
}

在这里插入图片描述

3:try中可能存在多个不同的异常对象,则必须通过多个catch来捕获异常

public class Test {public static void fun(int[] array){try{System.out.println(array[10]);//抛出的是数组越界异常System.out.println(10/0);//抛出的是算数异常}catch (ArithmeticException e){//没有处理数组越界异常,将交给该方法的调用者来处理//但该方法的调用者main()并没有处理,将交给JVM来处理e.printStackTrace();System.out.println("算数异常");}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("数组越界异常");}}public static void main(String[] args) {int[] array={1,2,3,4};fun(array);}
}

在这里插入图片描述

4:如果多个异常具有父子类关系,一定子类异常在前catch,父类异常在后catch ,否则语法错误。

public class Test {public static void fun(int[] array) {try {System.out.println(array[10]);//抛出的是数组越界异常System.out.println(10 / 0);//抛出的是算数异常}/*catch (RuntimeException e){e.printStackTrace();System.out.println("运行时异常");}*/ catch (ArithmeticException e){//没有处理数组越界异常,将交给该方法的调用者来处理//但该方法的调用者main()并没有处理,将交给JVM来处理e.printStackTrace();System.out.println("算数异常");}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("数组越界异常");}catch (RuntimeException e){e.printStackTrace();System.out.println("运行时异常");}}public static void main(String[] args) {int[] array={1,2,3,4};fun(array);}
}

在这里插入图片描述
下面是错误代码:

public class Test {public static void fun(int[] array) {try {System.out.println(array[10]);//抛出的是数组越界异常System.out.println(10 / 0);//抛出的是算数异常}catch (RuntimeException e){e.printStackTrace();System.out.println("运行时异常");} catch (ArithmeticException e){//没有处理数组越界异常,将交给该方法的调用者来处理//但该方法的调用者main()并没有处理,将交给JVM来处理e.printStackTrace();System.out.println("算数异常");}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("数组越界异常");}/*catch (RuntimeException e){e.printStackTrace();System.out.println("运行时异常");}*/}public static void main(String[] args) {int[] array={1,2,3,4};fun(array);}
}

在这里插入图片描述

三:finally关键字

在程序中有些特定的代码,不论程序是否发生异常,都需要被执行,比如程序中打开的资源:网站连接,数据库连接 ,IO流等,在程序正常或者异常退出时,必须对资源进行回收,此时必须使用finally来对资源进行回收。
1:有异常出现时:finally会被执行

public class Test {public static void fun(int[] array){try{System.out.println(array[10]);//存在数组越界异常}catch(ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("数组越界异常");}finally{System.out.println("finally被执行了");}}public static void main(String[] args) {int[] array={1,2,3,4,5};fun(array);}
}

在这里插入图片描述2:当没有异常时,finally还会被执行

public class Test {public static void fun(int[] array){try{// System.out.println(array[10]);//存在数组越界异常}catch(ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("数组越界异常");}finally{System.out.println("finally被执行了");}}public static void main(String[] args) {int[] array={1,2,3,4,5};fun(array);}
}

在这里插入图片描述3:异常没有被成功捕获,finally还是会被执行

public class Test {public static void fun(int[] array){try{System.out.println(array[10]);//存在数组越界异常}catch(ArithmeticException e){//捕获算数异常e.printStackTrace();System.out.println("算数异常");}finally{System.out.println("finally被执行了");}}public static void main(String[] args) {int[] array={1,2,3,4,5};fun(array);}
}

在这里插入图片描述

finally执行时机: finally一定会被执行,无论程序是否异常,finally执行的时机是方法返回之前(try或者catch中如果有return,会在这个return 之前执行finally),如果finally中也存在return语句,那么只会执行finally中的return,而不会执行try中的return。

public class Test {public static int  fun(int[] array){try{System.out.println(array[10]);//存在数组越界异常return 10;}catch(ArithmeticException e){//捕获算数异常e.printStackTrace();System.out.println("算数异常");} catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("数组越界异常");return 20;} finally{System.out.println("finally被执行了");return 100;}}public static void main(String[] args) {int[] array={1,2,3,4,5};int result=fun(array);System.out.println("result="+result);}
}

在这里插入图片描述【异常处理流程总结】
1:程序先执行 try 中的代码
2:如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
3:如果找到匹配的异常类型, 就会执行 catch 中的代码
4:如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
5:无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
6:如果上层调用者也没有处理的了异常, 就继续向上传递
7:一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止。

四:自定义异常类:

1:自定义异常类,然后继承来自Exception(默认是受查异常)或者来自RunTimeException(非受查异常)。
2:实现一个带String类型参数的构造方法,
参数含义:出现异常的原因
定义一个用户类,该用户有name,password两个成员变量:

public class Admin {//定义一个用户类,该用户有name,password两个成员变量public String name;public String password;public Admin(String name, String password) {this.name = name;this.password = password;}//登录方法public  void login(String name,String password) {if (!(this.name.equals(name))) {throw new NameException("用户名错误");}else if(!(this.password.equals(password))){throw new PasswordException("密码错误");}else{System.out.println("登录成功");}}
}

自定义 NameException 异常类,继承了RuntimeException:

public class NameException extends RuntimeException{//自定义 NameException 异常类,继承了RuntimeExceptionpublic NameException() {}public NameException(String message) {super(message);}
}

自定义PasswordException 异常类,继承了RuntimeException:

public class PasswordException extends RuntimeException{//自定义PasswordException 异常类,继承了RuntimeExceptionpublic PasswordException() {}public PasswordException(String message) {super(message);}
}

Test测试类:

public class Test {public static void main(String[] args) {Admin admin=new Admin("Admin","123456");try {admin.login("admin","123456");}catch (NameException e){e.printStackTrace();System.out.println("用户名错误");}catch (PasswordException e){e.printStackTrace();System.out.println("密码错误");}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/195392.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】特征工程:特征选择、数据降维、PCA

各位同学好,今天我和大家分享一下python机器学习中的特征选择和数据降维。内容有: (1)过滤选择;(2)数据降维PCA;(3)sklearn实现 那我们开始吧。 一个数据集中…

【Python】Loguru模块更简洁的日志记录库

Loguru: 更优雅的日志记录解决方案! loguru 是一个Python 简易且强大的第三方日志记录库,该库旨在通过添加一系列有用的功能来解决标准记录器的注意事项,从而减少 Python 日志记录的痛苦。 使用自带自带的 logging 模块的话,则需要…

Loguru:一个超酷的Python库

在项目中,了解代码运行情况至关重要,特别是遇到Bug需要排除问题的时候,而这正是日志记录发挥作用的地方。对于Python开发者来说,Loguru是一个简单但功能强大的日志记录库,它使得跟踪代码的行为变得轻松而高效。 什么是…

Nodejs--Express框架使用

目录 一.概念 二.项目目录结构 三.app.js 四.项目需要的中间件 五.Mysql连接 六.日志配置 七.实体模型配置 八.统一结果封装 九.app.js的详细配置 十.自定义登录拦截器 十一.route路由配置 十二.controller处理 十二:静态页面: 十三&#xff…

【C++入门】拷贝构造运算符重载

目录 1. 拷贝构造函数 1.1 概念 1.2 特征 1.3 常用场景 2. 赋值运算符重载 2.1 运算符重载 2.2 特征 2.3 赋值运算符 前言 拷贝构造和运算符重载是面向对象编程中至关重要的部分,它们C编程中的一个核心领域,本期我详细的介绍拷贝构造和运算符重载。 1. …

Java --- JVM之垃圾回收相关算法

目录 一、垃圾标记算法 1.1、垃圾标记阶段:对象存活判断 1.2、引用计数算法 1.3、可达性分析算法 1.4、GC Roots 二、对象的finalization机制 2.1、生存还是死亡? 三、查看GC Roots 3.1、使用MAT查看 四、使用JProfiler分析OOM 五、清除阶段算…

简单聊一聊幂等和防重

大家好,我是G探险者。 每年的双十一,618,电商系统都会面临这超高的流量,如果一个订单被反复提交,那电商系统如何保证这个订单之后执行一次减库存,扣款的操作? 这里就引入两个概念,…

【Linux进程】进程等待 与 进程替换 原理与函数使用

文章目录 一、进程等待1.1 意义 / 必要性1.2 进程等待的函数(wait / waitpid)1.3 status参数1.4 获取子进程status1.5 进程的阻塞等待与非阻塞等待 二、进程替换2.1 引言2.2 进程替换原理2.3 替换函数 一、进程等待 1.1 意义 / 必要性 为什么要有进程等…

【C++】泛型编程 ⑦ ( 模板类常用用法 | 模板类声明 | 模板类调用 | 模板类作为函数参数 )

文章目录 一、类模板基础用法1、类模板声明定义2、类模板使用3、类模板做函数参数 二、完整代码示例1、代码示例2、执行结果 一、类模板基础用法 1、类模板声明定义 上一篇博客中 , 【C】泛型编程 ⑥ ( 类模板 | 类模板语法 | 代码示例 ) 讲解了模板类的基础语法 , 模板类声明如…

从一到无穷大 #19 TagTree,倒排索引入手是否是优化时序数据库查询的通用方案?

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 文章主旨时序数据库查询的一般流程扫描维度聚合时间聚合管控语句 TagTree整体结构索引…

SQL零基础入门教程,贼拉详细!贼拉简单! 速通数据库期末考!(十)

SQL 函数 SQL 拥有很多可用于计数和计算的内建函数。 比如: AVG() - 返回平均值 COUNT() - 返回行数 MAX() - 返回最大值 MIN() - 返回最小值 SUM() - 返回总和 FIRST() - 返回第一个记录的值 LAST() - 返回最后一个记录的值 GROUP BY 学习SQL函数前&#xff0c…

【数据结构&C++】二叉平衡搜索树-AVL树(25)

前言 大家好吖,欢迎来到 YY 滴C系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! 目录 一.AVL树的概念二.AVL树节点的定义(代码…