java异常体系

一、基本概念

1.异常是程序运行过程中出现的错误。Java语言的异常处理框架, 是Java语言健壮性的一个重要体现
2.异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的
3.Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类

二、异常分类

这里写图片描述

1.Error——是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止
2.Exception——是程序本身可以处理的异常
1)运行时异常(非检查异常)
  • (1)运行时异常都是RuntimeException类及其子类异常
  • (2)程序中可以选择捕获处理,也可以不处理
  • (3)这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
  • (4)常见运行时异常:
    1)ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数”除以零”时,抛出此类的一个实例
    2) ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引
    3) ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常
    4) IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数
    5) IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出
    6) NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
    7) UnsupportedOperationException 当不支持请求的操作时,抛出该异常
2)非运行时异常(检查异常)
  • (1)非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类
  • (2)从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过
  • (3)如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常
  • (4)常见检查性异常:(不能编译通过)
    1)ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常
    2)IllegalAccessException 拒绝访问一个类的时候,抛出该异常
    3)InterruptedException 一个线程被另一个线程中断,抛出该异常
    4)IOException
    5) SQLException
注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理

三、异常处理机制——抛出异常,捕捉异常

1.抛出异常
  • 1)当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。
    运行时系统负责寻找处置异常的代码并执行。
2.捕获异常
  • 1)在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)
  • 2)运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未
    找到合适的异常处理器,则运行时系统终止。
  • 3)对于运行时异常、错误或可查异常,Java技术所要求的异常处理方式有所不同

    (1)由于运行时异常的不可查性,为了更合理、更容易地实现应用程序,Java规定,运行时异常将由Java运行时系统自动抛出,允许
    应用程序忽略运行时异常
    (2)对于方法运行中可能出现的Error,当运行方法不欲捕捉时,Java允许该方法不做任何抛出声明。因为,大多数Error异常属于永
    远不能被允许发生的状况,也属于合理的应用程序不该捕捉的异常
    (3)对于所有的可查异常,Java规定:一个方法必须捕捉,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉可查异常时,
    它必须声明将抛出异常

  • 4)一个方法所能捕捉的异常,一定是Java代码在某处所抛出的异常。简单地说,异常总是先被抛出,后被捕捉的

  • 5)任何Java代码都可以抛出异常,如:自己编写的代码、来自Java开发环境包中代码,或者Java运行时系统。无论是谁,都可以通过Java的
    throw语句抛出异常。
  • 6)从方法中抛出的任何异常都必须使用throws子句
  • 7)捕捉异常通过try-catch语句或者try-catch-finally语句实现

总体来说,Java规定:对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeException和Error。

四、异常的五个关键字

1.try…catch…finally
1) 格式
            try{   
                  //(尝试运行的)程序代码   
            }catch(异常类型 异常的变量名){   
                  // 异常处理代码   
            }finally{   
                  // 异常发生,方法返回之前,总是要执行的代码   
            }
2)try语句块,表示要尝试运行代码,try语句块中代码受异常监控,其中代码发生异常时,会抛出异常对象
3)catch语句块会捕获try代码块中发生的异常,并和自己的异常类型匹配,并在其代码块中做异常处理.catch语句可以有多个,用来匹配多个中的一个异常,一旦匹配上后,就不再尝试匹配别的catch块了
4)finally语句块
  • (1)这个语句块总是会在方法返回前执行, 而不管是否try语句块是否发生异常
  • (2)不管有木有出现异常,finally块中代码都会执行;
  • (3)当try和catch中有return时,finally仍然会执行;
  • (4)finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
  • (5)finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
5)应当要注意的问题:

(1)三个语句块均不能单独使用,三者可以组成 try…catch…finally、try…catch、try…finally三种结构,catch语句可以有
一个或多个,finally语句最多一个
(2)try、catch、finally三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。如果要在三个块中都可以访问,则需
要将变量定义到这些块的外面
(3)多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上
到下

2.throw
1)throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。
2)如果抛出了检查异常, 则还应该在方法头部声明方法可能抛出的异常类型。
3)如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息
3.throws
1) throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。
2) 仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。
3) 当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣一般在catch块中打印一下堆栈信息做个勉强处理

四、异常处理的一般原则

1.能处理就早处理,抛出不去还不能处理的就想法消化掉或者转换为RuntimeException处理。因为对于一个应用系统来说,抛出大量异常是有问题的,应该从程序开发角度尽可能的控制异常发生的可能。
2.对于检查异常,如果不能行之有效的处理,还不如转换为RuntimeException抛出。这样也让上层的代码有选择的余地,可处理也可不处理。
3.对于一个应用系统来说,应该有自己的一套异常处理框架,这样当异常发生时,也能得到统一的处理风格,将优雅的异常信息反馈给用户。

五、自定义异常(写一个类继承Exception或者RuntimeException)

参考网址

1.深入理解java异常处理机制
2.Java异常体系结构

注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。
ps : 有错误的还望各位大佬指正,小弟不胜感激

Java异常体系结构是Java语言中用于处理期间可能出现的错误和异常情况的一种机制。该体结构以`Throwable`类作为根节点,所有异常类都是它的子类,并且形成了一个树形结构。整个体可以分为两大分支:`Error`和`Exception`。 ### `Throwable`类 `Throwable`是所有异常类的基类,它定义了异常的基本属性和方法。`Throwable`有两个直接子类:`Error`和`Exception`。通过继承`Throwable`,这些子类能够获得关于异常的信息,比如堆栈跟踪等。 ### `Error`类 `Error`类代表的是严重的级问题,这些问题通常不是应用可以处理或恢复的。如,当JVM(Java虚拟机)遇到内存不足或者堆栈溢出等问题,会抛出`Error`类型的异常。常见的`Error`有`OutOfMemoryError`、`StackOverflowError`等。对于这类错误,通常不建议尝试捕获并处理它们,而是应该修复导致错误的根本原因。 ### `Exception`类 `Exception`类表示的是可以处理的异常情况。这类异常进一步分为异常(`RuntimeException`)和其他非异常(也称为受检查异常)。异常包括如`NullPointerException`、`IndexOutOfBoundsException`等,它们通常发生在中,但不需要强制捕获。而非异常如`IOException`、`SQLException`等,则必须被声明抛出或在代码中被捕获处理,否则编译器将报错。 #### 异常(RuntimeException) 异常是由逻辑错误引起的,比如访问空对象的属性、数组越界等。这些异常在编译不被检查,因此称为非受检查异常。虽然不需要强制捕获,但是良好的编实践要求开发者应该尽量避免此类异常的发生。 #### 非异常(受检查异常) 非异常是指那些在编译就会被检查到的异常,比如文件找不到(`FileNotFoundException`)、输入输出操作失败(`IOException`)等。如果一个方法可能会抛出这种类型的异常,那么它必须使用`throws`关键字声明该异常,或者在方法内部捕获并处理它。 ### 异常处理机制 Java异常处理机制采用面向对象的方式,允许开发者通过`try-catch`语句块来监控可能抛出异常的代码段,并提供相应的异常处理逻辑。此,还可以利用`finally`块确保无论是否发生异常,某些清理工作都能被执。当异常被抛出,JVM会查找匹配的`catch`块来处理这个异常。如果没有找到合适的处理,那么默认情况下,将会终止。 ### 示代码 下面是一个简单的Java异常处理示,演示了如何使用`try-catch-finally`结构: ```java public class ExceptionDemo { public static void main(String[] args) { int x = 1; int y = 0; try { System.out.println(x / y); // 可能抛出ArithmeticException } catch (ArithmeticException e) { System.out.println("除数不能为零"); } finally { System.out.println("无论是否发生异常,我都会"); } } } ``` 在这个子中,由于尝试执除以零的操作,这会导致`ArithmeticException`被抛出。此异常被`catch`块捕获,并打印出一条友好的错误消息。无论是否发生异常,`finally`块中的代码都会执,保证了资源的正确释放或其他必要的后续操作。 ### 使用建议 - 对于`Error`类型的问题,通常意味着更严重的问题,应着重于预防而不是捕获。 - 对于`Exception`,尤其是受检查异常,应当根据业务需求合理地进捕获和处理。 - 在编写方法,如果方法可能抛出受检查异常,则需要明确地在方法签名中用`throws`声明,以便调用者知道需要处理潜在的异常。 通过理解和正确使用Java异常体系结构,开发者能够编写更加健壮和易于维护的应用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值