Java中的异常总结详解(异常类型、声明异常、抛出异常、捕获异常)

您所在的位置:网站首页 血脂异常最常见的类型 Java中的异常总结详解(异常类型、声明异常、抛出异常、捕获异常)

Java中的异常总结详解(异常类型、声明异常、抛出异常、捕获异常)

2024-07-02 22:22| 来源: 网络整理| 查看: 265

Java 异常解析 前言一、异常概述二、异常类型1.系统错误(Error)2.编译时异常(Exception)3.运行时异常(RuntimeException) 三、处理编译时异常的更多知识1. 声明异常2. 抛出异常3. 捕获异常 四、在捕获异常中return的执行顺序

前言

    异常处理使得程序可以处理非预期的情景,并且继续正常的处理。     在程序运行过程中,如果 JVM 检测出一个不可能执行的操作,就会出现运行时错误(runtime error)。例如,如果使用一个越界的下标访问数组,程序就会产生一个ArraylndexOutOfBoundsException 的运行时错误。如果程序需要输入一个double 值,会得到一个 InputMismatchException 的运行时错误。     在 Java 中,运行时错误会作为异常抛出。异常就是一种对象,表示阻止正常进行程序执行的错误或者情况。如果异常没有被处理,那么程序将会非正常终止。该如何处理这个异常,以使程序可以继续运行或者优雅终止呢?本篇文章将介绍该主题。

一、异常概述

    异常就是程序在运行过程中出现的一些错误,我们通过面向对象的思想,把这些错误也用类来描述,那么一旦产生一个错误,即就是创建了某一个错误的对象,这个对象就是我们所说的异常对象。     在这之前也见过很多的异常错误,例如: (1)IndexOutOfBoundsException:

ArrayIndexOutOfBoundsException 数组角标越界异常 角标不在数组范围内

StringfIndexOutOfBoundsException 字符串角标越界异常 角标不在字符串范围内

(2)NullPointerException     空指针异常 对null调用其成员。 (3)ArithmeticException     数学运算异常 非法的数学运算。 (4)ClassCastException     类型转换异常 将类进行错误的强制转换。 (5)NumberFormatException     数字格式化异常 将数字字符串进行解析。 (6)InputMismatchException     输入不匹配异常 在输入时输入非法数据。 (7)ParseException     时间解析异常 非法的时间格式。 (8)StackOverFlowError     栈内存溢出异常 函数递归。 (9)OutOfMemoryError     堆内存异常 数组空间开辟过大 程序中对象太多。

    为了演示异常处理,在这里举了个例子,进行讲解:

public static void main(String[] args) { int[] arr = {1,2,3,4,5}; int num = getNumber(arr,10); System.out.println(num); } private static int getNumber(int[] arr, int i) { return arr[i]; //如果arr为null NullPointerException //如果i越界 ArrayIndexOutOfBoundsException }

    如上述代码所示,对于一个有返回值的函数而言,如果操作计算是正确的话,肯定会有一个正常的返回值,如果操作计算是错误的话,从函数的角度而言 会不会有正常的返回值呢?不会;     本质上,大部分的错误,其实都是由JVM发现并抛出的 当然我们也可以手动去判断。

private static int getNumber(int[] arr, int i) { //return arr[i];//是由JVM来进行判断的 //模拟JVM的操作 用手动的判断模拟JVM自动的发现 if (arr == null) { //产生一个空指针异常的问题对象 //用throw(抛出)关键 将产生的问题告知调用者 throw new NullPointerException(); //一旦上述抛出一个问题 此函数立马中断 //类似于return 正常结束(弹栈) //throw非正常结束(中断 强制弹栈 并抛出问题给调用者) } if (i = arr.length) { //产生一个数组角标越界异常的问题对象 throw new ArrayIndexOutOfBoundsException(); //throw new StackOverflowError(); //PS 一旦出现错误 抛出问题即可 但是最好抛出最相关最精确的问题 } return arr[i]; }

    getNumber函数如果发生了问题是直接将问题抛给主函数的,但是主函数也没有处理这个问题,主函数接着将问题抛给调用者JVM,JVM才不帮你解决 结果就是程序中断了!     JVM----->调用main----->调用getNumber----->getNumber出现异常----->抛出给main----->main没有处理----->抛出传递给JVM----->JVM直接中断。     PS:当然 函数内部如果出现问题,也可以将问题在内部处理 处理后 就不需要向上层抛出。

二、异常类型

    既然错误的原因有很多,描述错误的类也有很多,那么这种情况就产生了一个大的家族/体系,这里面全都是异常错误类,我们叫做异常体系。     对于异常体系而言,大家都是错误,只不过所产生的原因不太一样,不断的进行向上抽取共性,最终抽出Throwable这个接口(可以被抛出的),但凡是异常对象,无论原因,都可以被抛出。     Throwable类是 Java 语言中所有错误或异常的超类,只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。     异常是对象,而对象都采用类来定义。异常的根类是 java.lang.Throwable。关系图如下: 在这里插入图片描述     注意:类名 Error、Exception 和 RuntimeException 有时候容易引起混淆。这三种类都是异常,这里讨论的错误都发生在运行时。     Throwable 类是所有异常类的根。所有的 Java 异常类都直接或者间接地继承自Throwable。可以通过继承 Exception 或者 Exception 的子类来创建自己的异常类。     这些异常类可以分为三种主要类型:系统错误、编译时异常和运行时异常。

1.系统错误(Error) 系统錯误(system error) 是由 Java 虚拟机抛出的,用 Error 类表示。Error 类描述的是内部系统错误。这样的错误很少发生。如果发生,除了通知用户以及尽量稳妥地终止程序外,几乎什么也不能做。 在这里插入图片描述

OutOfMemoryError :内存耗尽 ; NoClassDefFoundError :无法加载某个Class ; StackOverflowError :栈溢出。

2.编译时异常(Exception) 编译时异常:Exception及其子类(除了RuntimeException),在编译时期抛出的异常,在编译期间检查程序是否可能会出现问题,如果可能会有,则预先防范:捕获 声明。 在这里插入图片描述

Exception 则是编译时异常,它可以被捕获并处理。 某些异常是应用程序逻辑处理的一部分,应该捕获并处理。例如:

NumberFormatException :数值类型的格式错误;FileNotFoundException :未找到文件;SocketException :读取网络失败。

还有一些异常是程序逻辑编写不对造成的,应该修复程序本身。例如:

NullPointerException :对某个 null 的对象调用方法或字段;IndexOutOfBoundsException :数组索引越界。 3.运行时异常(RuntimeException) 运行时异常(runtime exception) 是用 RuntimeException 类表示的,它描述的是程序设计错误,例如,错误的类型转换、访问一个越界数组或数值错误。运行时异常通常是由 Java 虚拟机抛出的。RuntimeException是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类,可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明,指的就是这些问题不需要提前被预防(本质上也可以的,只不过没必要),因为只有在真正运行的时候才能发现是否发生问题,一旦在运行期间发生了问题,则一般不会修正,程序直接终端。

在这里插入图片描述

    RuntimeException、Error 以及它们的子类都称为免检异(unchecked exception )。所有其他异常(编译时异常)都称为必检异常(checked exception), 意思是指编译器会强制程序员检査并通过 try- catch 块处理它们,或者在方法头进行声明。

    在大多数情况下,免检异常都会反映出程序设计上不可恢复的逻辑错误。例如,如果通过一个引用变量访问一个对象之前并未将一个对象陚值给它,就会抛出 NullPointerException异常;如果访问一个数组的越界元素,就会抛出IndexOutOfBoundsException 异常。这些都是程序中必须纠正的逻辑错误。免检异常可能在程序的任何一个地方出现。为避免过多地使用 try-catch 块,Java 语言不强制要求编写代码捕获或声明免检异常。

Java规定:

必须捕获的异常,包括 Exception 及其子类,但不包括 RuntimeException 及其子类,这种类型的异常称为Checked Exception。不需要捕获的异常,包括 Error 及其子类, RuntimeException 及其子类。 三、处理编译时异常的更多知识 1. 声明异常

    在 Java 中,当前执行的语句必属于某个方法。Java 解释器调用 main 方法开始执行一个程序。每个方法都必须声明它可能抛出的必检异常的类型。这称为声明异常( declaring exception)。只对编译时异常进行声明,、告知方法的调用者有异常。     为了在方法中声明一个异常,就要在方法头中使用关键字 throws, 如下所示:

public void myMethodO throws IOException

    关键字 throws 表明 myMethod 方法可齙会抛出异常 IOException。如果方法可能会抛出多个异常,就可以在关键字 throws 后添加一个用逗号分隔的异常列表:

public void myMethodO throws Exceptionl, Exception2,… ,ExceptionN

    注意:如果方法没有在父类中声明异常,那么就不能在子类中对其进行继承来声明异常。

2. 抛出异常

    检测到错误的程序可以创建一个合适的异常类型的实例并抛出它,这就称为抛出一个异常(throwing an exception)。这里有一个例子,假如程序发现传递给方法的参数与方法的合约不符(例如,方法中的参数必须是非负的,但是传入的是一个负参数),这个程序就可以创建 IllegalArgumentException 的一个实例并抛出它,如下所示:

IllegalArgumentException ex = new II1egalArgumentException("Wrong Argument"); throw ex;

    或者,大多数使用下面的语句:

throw new IllegalArgumentException("Wrong Argument");

    注意:IllegalArgumentException 是 Java API 中的一个异常类。通常,JavaAPI 中的每个异常类至少有两个构造方法:一个无参构造方法和一个带可描述这个异常的 String 参数的构造方法。该参数称为异常消息(exceptionmessage), 它可以用 getMessage()获取。     提示:声明异常的关楗字是 throws, 抛出异常的关键字是 throw。

3. 捕获异常

    现在我们知道了如何声明一个异常以及如何抛出一个异常。当抛出一个异常时,可以在try-catch 块中捕获和处理它; try-catch-finally     try语句块中:放的是可能出现问题的代码,尽量不要把不相关的代码放入到里面,否则会出现截断的问题。

try{ codeA throw ... codeB }

    如果throw这个地方一旦抛出异常 codeB就不会执行了 建议把codeB放到后面。

    catch语句块中:放的是出现问题并捕获后,处理问题的代码code,如果问题在try语句块中没有出现 则catch中不会运行。

catch(Exception e) { code }

    finally语句块中:放的是不管问题异常是否产生 都要执行的代码code。

finally{ code//关闭资源(IO 数据库 网络),结尾处理的一些工作 } 四、在捕获异常中return的执行顺序


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3