Java异常处理机制

来源:互联网 发布:ray kurzweil 骗 知乎 编辑:程序博客网 时间:2024/05/22 08:13

一. 异常定义

 

异常是程序运行时发生的意外或错误,导致程序运行失败,称为异常。

异常也是现实生活中、程序开发或使用中一个真实的存在的事物,Java也用类的方式进行了描述,并用对象的方法进行了封装体现。

二. 异常处理机制
当程序发生错误时,程序如何处理错误,具体来说,当程序发生错误后,异常处理机制将调整程序的执行流程,程序的控制权转移到异常处理器,异常处理机制将会按照给定的处理方式让程序安全退出,并将错误信息返回给用户或程序的维护员,加以分析维护。

在早期或比较传统的异常处理方法,是在程序退出时,返回一个值,或者直接打印一个错误信息,通过这个告诉使用程序或维护程序的人,程序运行过程中到底发生什么错误,可是弊端是,如函数返回-1代表出现异常,但是如果函数本身确实要返回-1给调用端,那么这个值时就会出现混淆可读性降低

 

三. 异常体系:

异常和异常之间都存在一些共性,从而进行向上抽取,Java就存在一个Throwable这么一个类,Throwable是所有异常类的超类,继承该类的任何类或对象都具备可抛性。

Throwable

     |---Error

         …(其他子类)

     |---Exception

         …(其他子类)

           |---RuntimeException

                 …(其他子类)

Error:Error体系描述了Java运行系统中的内部错误,内存不足,资源耗尽等异常,程序或程序员是无能去阻止或处理异常的发生,所以这种异常,在程序设计时候,一定不给于任何代码做处理或声明,RuntimeExceptionError可以在任何代码中产生,它们不需要由程序员显示的抛出,一旦出现错误,那么相应的异常会被自动抛出程序员一般是无能为力去处理的,Java虚拟机出做响应的处理。

RuntimeException:这个体系包括错误类型的转换、数组下标越界,引用类型的空指针异常等等,如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常,这种异常在设计时,不用给与声明和处理,应该立即结束程序,告诉程序开发维护人员,进行程序的修正。

四. throwsthrow的区别:

使用位置:

àthrows使用在函数上

public void show()throwsNoSuchFieldException{……….}


àthrow使用在函数内部

public void show(){throw newNoSuchFieldException(“没有找到指定的属性”);}


使用方法:

àthrows用来抛出异常类,抛出多个用逗号隔开

public void show()throwsNoSuchFieldException, NoSuchMethodException{……….}


àthrow用来抛出异常对象,只能抛出一个异常对象

public void show(){throw newNoSuchFieldException(“没有找到指定的属性”);}


五. 异常的分类:

1.     将异常按照问题发生的严重性划分:

严重异常: Errorà无法处理,无法补救,也无需捕获,只能交给JVM处理,如果JVM都无法处理,那么只能让程序停止,一般JVM的处理方式的停止程序运行,现实错误信息,及堆栈信息追踪。

可处理异常: Exceptionà可以或有可能进行处理的异常,对于这种异常需要对其进行捕获try{}和处理catch(Exception e){}或者说也可以不处理,可以不处理的主要针对RuntimeException

2.     可处理异常又可以分为编译时异常和运行时异常

编译时异常(CheckedException):

编译时异常,就是在程序编译时,如果未对throw抛出的异常进行声明(throws)或者未异常语句块进行try{}catch(Exception e){}处理的话,编译将无法通过,提示必须进行处理或者异常声明,该异常被表示,代表该异常可以被处理。

运行时异常(UncheckException):

运行时异常,就是发生的异常或错误,不用进行处理或声明,在编译的时候编译器不会去做是否有被声明或处理的动作,该异常的发生,建议不需要处理,停止程序运行,提示修正代码。

六. 异常的处理

方式1:

       

  try          {                 //这里定义可能发生异常的代码;(异常捕获检测)          }          catch (Exception e)          {                 //这里定义异常处理语句;          }          finally          {                 //这里定义的是无论如何都会执行到的语句;          }

 

  方式2:

     

  try          {                 //这里定义可能发生异常的代码;(异常捕获检测)          }          catch (Exception e)          {                 //这里定义异常处理语句;          }

  方式3:

      

 try          {                 //这里定义可能发生异常的代码;(异常捕获检测)          }          finally          {                 //这里定义的是无论如何都会执行到的语句;          }

注意: finally语句块中书写代码的都是一定会被执行的,一般会定义用来关闭资源,如关闭数据库连接,流资源关闭等,用来释放代码,但是当在trycatch语句中出现System.exit(0);退出语句时,finally语句块中的代买将不会被执行。

七. 自定义异常

1.     定义:自定义异常就是Java定义自身定义的异常之外的特有异常,是程序开发人员未符合程序开发需求和逻辑设计需求,定义的一种特有异常,继承自Exception类或RuntimeException子类。

2.     如何定义一个自定义异常

A.     一个类如果要称为一个一场类,那么该类一定要具备异常的共性特点,和Java异常类存在所属关系,必须继承Exception类或RuntimeException子类,让其具备可抛性,具备异常异常操作的共性方法,可以使用父类已经具备的功能。

class MyExceptionextends Exception{        MyException(String message)        {               super(message);        }}


 

八. 异常处理的原则

1.     多个异常声明存在,必须需要多个对应的catch语句进行处理(一个try对应多个catch)

2.     一个try对应多个catch语句块的时候,更父类的catch语句块要放在下面,否则,子类的语句块将永远无法执行到,编译将不会通过。

3.     catch语句块中的异常处理方法,尽可能的有意义,尽可能的有针对性,不能简单的使用printStackTrace();等异常输出语句,更不能不书写任何语句。

4.     当某个异常捕获到之后,无法处理时,可以继续在catch语句中抛出,

       

 try              {                     thrownew MyException("异常");              }              catch(MyException e)              {                      throw e;              }

     如果该异常处理不了,但并不属于该功能应该出现的异常,可以先将异常转换后,再抛出和该功能相关的异常;或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,当调用者知道并处理,也可以将捕获异常处理后,转为新的异常。

try              {                     thrownew AException("A");              }              catch(AException e)              {                     //先对AException进行处理                      thrownew BException("B");              }


5.     throw后面不能跟其他任何语句

try              {                     thrownew AException("A"); //System.out.println("异常抛出了");//上面这行输出语句是永远也执行不到的,//因为throw new AException("A");抛出一个异常之后程序就跳转了//所以就永远无法被执行,编译无法通过。              }


九. 在子父类覆盖时需要注意的事项

1.     子类抛出的异常必须是父类的异常的子类或者子集。

2.     如果父类或接口没有异常抛出时,子类在覆盖的时候,只能try{}catch(Exception e){};进行捕获处理,或者编译不通过。

十. 关于throw语句后的语句永远无法执行到的问题

1.      

 try {       throw new AException(“XXX错误”);       System.out.println(“这句话永远都执行不到….”);}


    这种写法是错误的,因为异常使用throw抛出后,程序就进行了跳转,进入了catch语句块,或者进入finally语句块,所以throw后面的代码是永远都无法执行到的,编译失败,建议这个地方不要书写代码。

2.      

class Demo{     public static void main(String[] args)     {            try            { //这里调用showExce()后抛出异常,这个中方式是将异常封装在了方法里面,//但是对于程序来判定,这个方法是有可能会发生异常,下面的语句还有可//能被执行到,所以编译通过                   showExce();                   System.out.println("A");            }            catch(Exception e)            {                   System.out.println("B");            }            finally            {                   System.out.println("C");            }           System.out.println("D");     }//showExce()方法抛出并声明了异常     public static void showExce()throws Exception     {            throw new Exception();     }}