欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java Exception

程序员文章站 2022-07-15 12:54:30
...

异常处理

安全检查及错误处理

编程中的对于带参方法进行方法传参时,必须对所传参数进行安全检查,不能假定使用者一定会传入正确的值。但如果检查到传入参数不合法时,由方法去终止程序的运行显然是一个问题。不应该让方法来终止程序——应该由方法的调用者来决定是否终止程序。

当进行安全检查时,若传入参数不合法,而如上述由方法去终止程序又显然是不合理的,此时就可以由方法去抛出一个异常,(throw)

当异常被抛出时,正常的执行流程就会被中断,而异常则会被从方法处转移到其调用者处,由调用者决定如何处理异常

进行异常处理的好处

  • 它能够使方法抛出一个异常,并由调用者决定如何处理该异常
  • 异常处理的根本优势就是将检查错误(由被调用者处)从处理错误(由调用者方法完成)中分离出来

异常的体系结构

Throwable 
    |-- Error 
         |-- OutOfMemoryError 内存溢出 
         |-- VirtualMatchineError 虚拟机崩溃
         |-- ... 
    |-- Exception 
         |-- ClassNotFoundException 试图使用一个不存在的类 
         |-- IOExceprtion IO异常 
         |-- RuntionException 运行时异常 
               |-- NotNullPointException 空指针异常 
               |-- IndexOutOfBoundsExcepton 数组下标越界 
               |-- ArithmeticException 一个整数除以0 
               |-- IllegalArgumentException 传入方法参数不合法 
         |-- ...

Throwable类是所有异常类的根类,所有异常类都直接或间接的继承自Throwable类。

异常的分类

异常可以分为三种类型:系统错误(Error)、编译时异常(Exception)、运行时异常(RuntimeException)

系统错误(Error)

该异常是由java虚拟机抛出的,描述了系统内部错误,很少发生,发生时除了终止程序,什么都做不了

OutOfMemoryError : 内存溢出
VirtualMatchineError 虚拟机崩溃
...

编译时异常(Exception)

该异常描述了程序或外部环境所引起的错误,这些错误可以被捕获和处理.

在IDE中进行编码时,如果出现编译异常,那么IDE会出现错误提示。

ClassNotFountException
IOException
...

运行时异常(RuntimeException)

描述了程序设计的错误,运行时异常通常是由java虚拟机抛出的。

在IDE中进行编码时,若出现运行时异常IDE不会有任何提示,因为运行时异常通常表现为程序的逻辑错误。

编译器不要求对抛出的运行时异常进行处理,也就是说既不捕获也不声明抛出

ArithmeticException  一个整数除以0 
NullPointException 
IndexOutOfBoundsException 
IllegalArgumentException  传递给方法的参数不合法,或者不合适
...

注意

免检异常(Unchecked Exception):

Error、RuntimeException以及它们的子类都称之为免检异常(Unchecked Exception):通常反映了程序设计上不可恢复的逻辑错误,不要求在方法中显示声明Error和RuntionException

必检异常(Checked Exception):

所有的其他异常都称为必检异常(Checked Exception):意思是说编译器会强制要求程序员检查并通过try-catch处理或者在方法头声明(throws) 每个方法都必须声明它可能抛出的必检异常

异常的三种处理方式

异常处理的三种操作:声明一个异常(throws)、抛出一个异常(throw)、捕获一个异常(try-catch-finally)

声明一个异常(throws)

对于方法抛出的异常,可以采用在当前方法头中声明一个异常的方式进行处理

public void test(...) throws Exception {
    ...
}

注意:在继承过程中,如果父类定义的方法有抛出异常,
那么子类在继承父类方法时,可以不抛出异常,
或者抛出和父类相同或者更小的异常

抛出一个异常(throw)

在编码时,对将可能发生的错误可以采用抛出异常的方法进行处理,以便当异常发生时方法的调用者进行处理,其格式如下:

throw new Exception(...);
自定义异常

当系统类库中提供的异常类不能满足需要时,我们需要自定义异常类

自定义异常需要继承自系统的编译时异常或者运行时异常,若要输出相应 的异常信息,可以自定义构造器方法并调用super()

在IDE中编码时,可以通过IDE自动编写并重载构造器

捕获一个异常 (try-cathc-finally)

处理异常的代码称为异常处理器,可以从当前方法开始,
沿着方法调用链, 按照异常的反向传播方向找到该处理器

一个通用的父类可以派生出各种子类。如果一个catch块可以捕获一个父类异常,
那么它就能够捕获 那个父类的所有子类的异常对象,因此在catch块中异常被指定的顺序时非常重要的,如果父类的catch块出现在子类的catch块之前 就会发生编译错误

在JDK7 后对于使用同样的处理代码处理多个异常的情况,可以使用新的多捕获
特征 (multi-catch feature) 简化异常的代码编写。语法是:

catch (Exception1 | Exception2 | Exception3 | ... e) { ... }

注意:该语法下,catch中的Exception之间不能存在继承关系

try/catch/finally的使用
  • try: 在try代码块中编写可能会发生异常的代码
  • catch: 在catch代码块中捕获try可能会发生的异常以及在该异常发生后需要进行的处理操作
  • finally: 有些特定的代码无论异常是否发生都需要执行,finally用于执行这一类代码,以避免当程序发生时异常进行跳转时,这一部分代码无法执行的情况。如释放一些资源等
  • try不能单独使用,必须和catch或者finally结合才能使用,也就是说catch和finally都不是必须的,但至少出现一个

注意:finally块中一般不谢return,try-catch中一旦执行return,那么做两件事:1. 将返回值存入JVM缓冲区中 2. 如果有finally, 则现将finally执行完,然后结束方法,返回缓冲区中的值

捕获异常的注意点:
  1. 如果可能捕获的异常之间存在继承关系,那么子类应该写在前边
  2. catch()中可以捕获多个异常, 但多个异常之间不能有继承关系
    try{}catch(异常名1 | 异常名2 e){}
  3. try/catch/finally结构中try不能单独存在。可以分别符catch或finally结合,或者三者都存在
相关标签: java exception