[01] 异常的概念和处理

1、异常和错误

Java作为面向对象的语言,自然把系统发生的不正确的事件也封装成了Java对象。比如一个不存在的对象,我们却试图调用它的方法,自然是行不通的,这个不正确的事件,也就被封装成为了我们常见的NullPointerException对象。

即是说,在Java程序的运行过程中,如果发生了意外事件(发生了错误或异常),则该意外会被封装成为一个对象,并把它提交给运行时的系统,寻求相应的代码来处理。意外事件在Java中分为两类,即错误异常;而把这个意外对象的生成和提交过程,我们称之为抛出。

在Java中:

  • 错误 - 不受控的,程序无法处理的
  • 异常 - 容易排查的,可以处理的

2、异常的体系

万物皆可抛,Throwable就是Java语言中所有错误和异常的父类,其两个子类:Error(错误)、Exception(异常)

Error是程序无法处理的,比如OutOfMemoryError、ThreadDeath等,出现如此情况我们往往无能为力,只能交给JVM自行处理,大多数情况下,JVM会选择终止线程(真是简单粗暴...);而Exception就是程序可以处理的异常,也是我们重点要理解的部分。

Exception的分类

在异常中,又分为两种,CheckedException(受检异常)和UncheckedExcpeiton(不受检异常),其中:

  • CheckedException 要求我们必须处理(要不然为什么叫CheckedExcpetion呢),使用 try catch 语句块,否则在编译阶段就无法通过(所以称之为编译期异常
    • 如大名鼎鼎的 IOException,要求我们必须捕捉处理
  • UncheckedException 发生在运行期(所以称之为运行期异常 RuntimeException),具有不确定性,主要是程序的逻辑问题所引起的,难以排查
    • 如 NullPointerException(空指针异常)、IndexOutOfBoundsException(数组越界异常)

3、异常的处理

3.1 try catch

对于可能发生异常的代码,我们要使用 try 语句块来进行包裹,与 try 相呼应的还要有 catch 语句块。即 try 用来检测不安全的代码,用来发现异常,而一旦某条语句出现了异常,则从此处中止,后面的代码不再执行,而是直接跳转到异常处理的代码块中,即提到的 catch 语句块。

所以:

  • try 包括需要检测的代码
  • catch 发生异常时进行捕获,并进行处理
  1. public static void main(String[] args) {
  2. Date date = null;
  3. try {
  4. long time = date.getTime();
  5. System.out.println(time);
  6. } catch (NullPointerException e) {
  7. System.out.println("空指针异常发生了,好像我应该做些什么");
  8. }
  9. }

(注意:这里只是使用运行期异常作为示例,实际上RuntimeException是不需要在编译阶段专门进行异常处理的,即不写try catch也行)

如上例:因为 line5 试图调用空对象的一个方法,所以会发生 NullPointerException,所以 line6 会跳过不执行,而直接执行 catch 块中的内容,即 line9,打印输出 “空指针异常发生了,好像我应该做些什么”

整个过程就像打棒球,发生异常就像投手丢出了棒球,这个棒球就是异常;而捕获异常就像接住棒球。

3.2 多个catch

catch 紧跟在 try 语句之后,也就是用来进行异常处理的部分,实际上 catch 可以写多个,分别用来捕获不同类型的异常,必须从小到大(即从子类到父类)的顺序进行捕获,否则会出现编译错误,且某异常只被捕捉一次,即第一个符合的 catch 处捕获。

  1. public static void main(String[] args) {
  2. Date date = null;
  3. int[] arr = new int[]{0, 1, 2};
  4. try {
  5. int i = arr[5];
  6. System.out.println(i);
  7. long time = date.getTime();
  8. System.out.println(time);
  9. } catch (NullPointerException e) {
  10. System.out.println("空指针异常发生了,好像我应该做些什么");
  11. } catch (IndexOutOfBoundsException e) {
  12. System.out.println("数组越界了");
  13. } catch (Exception e) {
  14. System.out.println("发生了异常");
  15. }
  16. }

我们把之前的例子改一下,如上,按照刚才我们提到的,这里可能出现数组越界和空指针异常,所以我们写了两个catch,可能还有其他我们没想到的异常,所以我们再捕捉了一个异常的父类Exception。这个例子最后只会输出 "数组越界了",因为异常只被捕捉一次,且后面的代码不再执行。

  1. public static void main(String[] args) {
  2. Date date = null;
  3. int[] arr = new int[]{0, 1, 2};
  4. try {
  5. int i = arr[5];
  6. System.out.println(i);
  7. long time = date.getTime();
  8. System.out.println(time);
  9. } catch (Exception e) { //错误的写法,异常捕获的顺序只能从子类到父类
  10. System.out.println("发生了异常");
  11. } catch (NullPointerException e) {
  12. System.out.println("空指针异常发生了,好像我应该做些什么");
  13. } catch (IndexOutOfBoundsException e) {
  14. System.out.println("数组越界了");
  15. }
  16. }

注意catch异常的顺序,如上例中的写法是无法通过编译的,因为Exception是所有异常的父类,而catch块必须按照从子类到父类的顺序进行编写。

3.3 finally

在异常处理中,还有一个语句块叫 finally,可以不写,一旦写上,那么有且只能有一个finally语句块,该部分的代码内容总是会执行的。一般是跟在最后的catch块之后。

  1. public static void main(String[] args) {
  2. Date date = null;
  3. int[] arr = new int[]{0, 1, 2};
  4. try {
  5. int i = arr[5];
  6. System.out.println(i);
  7. long time = date.getTime();
  8. System.out.println(time);
  9. } catch (NullPointerException e) {
  10. System.out.println("空指针异常发生了,好像我应该做些什么");
  11. } catch (IndexOutOfBoundsException e) {
  12. System.out.println("数组越界了");
  13. } catch (Exception e) {
  14. System.out.println("发生了异常");
  15. } finally {
  16. System.out.println("我总是要执行的");
  17. }
  18. }

如上例中,除了输出 “数组越界了”,还始终会输出 “我总是要执行的”。不论程序是否发生异常,finally代码块总是会执行,所以finally一般也用来关闭资源。

需要注意的是,之前提到finally是可选的,即可以只有try和catch,同时要知道的是:

  • 可以只有try和finally
  • 可以只有try和catch
  • 不能只有try

3.4 异常处理中的return

在Java语言的异常处理中,finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定会执行。而return意味着结束了对当前函数的调用并跳出这个函数体,那么如果try块中或者catch块中出现了return,finally又如何是好?

我们看这样一道题,下面的函数最终会返回多少?

  1. 链接:https://interview.nowcoder.com/questionTerminal/5a6ea98ed42347fe81c950a1a206dc7e?toCommentId=77575
  2. 来源:牛客网
  3. public static int func (){
  4. try{
  5. return 1;
  6. }catch (Exception e){
  7. return 2;
  8. }finally{
  9. return 3;
  10. }
  11. }

只需要记住,无论如何finally语句都要执行(除非调用了System.exit()方法)。同时,如果:

  • finally中没有return,那么不会影响try或catch中return的结果,但是finally还是会执行的
  • finally中有return语句,那么会覆盖掉try或catch中的return的结果,再进行返回
  1. public static int fun() {
  2. int i = 0;
  3. try {
  4. return i;
  5. } catch (Exception e) {
  6. return -1;
  7. } finally {
  8. ++i;
  9. }
  10. }

如上例,(前提是finally中没有return,否则会覆盖值)当执行到return时,结果会被保存等待finally执行完毕后返回,这个时候无论finally内部如何改变这个值,都不会影响返回结果。最终返回0。

时间: 2024-07-29 15:51:52

[01] 异常的概念和处理的相关文章

Python(八) —— 异常(概念、捕获、传递、抛出)

异常的概念 捕获异常 异常的传递 抛出异常 异常的概念 程序在运行时,如果 Python 解释器 遇到 到一个错误,会停止程序的执行,并且提示一些错误信息,这就是 异常 程序停止执行并且提示错误信息 这个动作,我们通常称之为:抛出(raise)异常 捕获异常 1.简单的捕获异常语法 在程序开发中,如果 对某些代码的执行不能确定是否正确,可以增加 try(尝试) 来 捕获异常 捕获异常最简单的语法格式 try: 尝试执行的代码 except: 出现错误的处理 try 尝试,下方编写要尝试代码,不确

Java多线程系列--“基础篇”01之 基本概念

多线程是Java中不可避免的一个重要主体.从本章开始,我们将展开对多线程的学 习.接下来的内容,是对“JDK中新增JUC包”之前的Java多线程内容的讲解,涉及到的内容包括,Object类中的wait(), notify()等接口:Thread类中的接口:synchronized关键字. 注:JUC包是指,Java.util.concurrent包,它是由Java大师Doug Lea完成并在JDK1.5版本添加到Java中的. 在进入后面章节的学习之前,先对了解一些多线程的相关概念.线程状态图

Java学习:异常的概念

异常 异常概念 异常:指的是程序在执行过程中,出现的非正常的情况,最终导致JVM的非正常停止. 在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出一个异常对象.Java处理异常的方式是中断处理. 异常体系 异常机制其实是帮助我们找到程序中的问题,异常的根类是java.lang.Throwable,其下有两个子类:java.lang.Error与java.lang.Exception,平常所说的异常指java.lang.Exception java.lang.Thr

01.异常捕获

什么是异常? 解释:语法上没有错误,在程序运行的过程当中,犹豫某些原因,程序出现了错误,不能再正常运行. 我们在程序中经常会出现各种各样的异常,如果想要程序坚强一点, 我么应该经常性的的使用try-catch来进行异常捕获. 窍门: 哪行代码有可能出现异常,我们就try它一下 语法: try { 可能会出现异常的代码; } catch { 出现异常后要执行的代码; } 执行过程: 如果try中的的代码,没有出现异常,catch中的代码不会被执行. 如果try中的代码出现了异常,在出现异常的代码之

01.面向对象的概念

(1)类是抽象的概念,仅仅是模板,比如说:"人"类. (2)对象是一个你能够看得到,摸得着的具体实体. (3).类不占内存,对象才会占内存. (4).类是模子,确定对象将会拥有的特征(属性)和行为(方法). 类的定义: 类的定义语法: [访问修饰符]class 类名 { 成员; ... } (1)类中可以包含变量的定义,方法. 类的实例化; 语法: 类 实例名=new 类(); 类的成员访问: 实例名.属性; 实例名.方法名(); 写好了一个类之后,我们需要创建这个类的对象(在同一个命

01.数据库基本概念

a. 数据库基本概念 i. 数据库:是表和数据库访问对象的集合,其中表分别存储了不同的实体信息,每一行数据对应一个实体的描述信息 i. 实体与记录: 1. 实体是所有客观存在的,可以被描述的事物 2. 记录:数据库中存储的数据表格,每一"行"实际上对应一个实体,这样的一行,在数据库中,通常叫做一条"记录" ii. 数据库管理系统(DNMS):是一种系统软件,由一个互相关联的数据集合和一组访问数据的程序构成,主要功能是维护数据库,并有效地访问数据库中各个部分的数据 i

异常的概念

程序正常的情况下可以有顺利运行,遇到用户非法输入,文件找不到磁盘空间已满.数据库连接错误等问题,如果程序不处理,就会崩溃. 异常的类型 1,异常的根类型:java.lang.Thtowable 只有它或它的子类类型,才能用于catch(异常类型e)语句中的异常类型,用于“捕获异常” 换句话说,如果要自定义异常,必须继承Throwable或他的子类 2.Throwable的两大子类:Error和Exception Error:合理的应用程序不应该通过捕获来解决的严重错误.例如:VirtualMac

01 http协议概念及工作流程

一:HTTP协议 重要性: 无论是以后用webserverice ,还是用rest做大型架构,都离不开对HTTP协议的认识. 甚至可以简化的说: webservice = http协议+XML Rest = HTTP协议 + json 各种API,也一般是用http+XML/json来实现的. 往小说:做采集,小偷站,也需要对HTTP协议有所了解, 以及Ajax,对HTTP协议有了解之后,学习Ajax是非常容易理解的. 什么是协议: 答:计算机中的协议和现实中的协议是一样的, 一式双份/多份.

异常的概念和异常体系

原文地址:https://www.cnblogs.com/wulinmiao/p/12153161.html