面向对象——异常

来源:互联网 发布:40本网络禁书名字 编辑:程序博客网 时间:2024/05/04 14:43
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

9.面向对象――异常

9.1异常的概念

异常:程序运行时期发生的不正常情况.

Java用面向对象的思想,对程序运行过程中发生的不正常情况进行了描述和封装,描述不正常情况的类称为异常类.

以前,是将正常代码和问题处理代码相结合,如C语言是通过大量的if …else语句来处理异常情况,耗费资源且效率低,导致代码出现的问题多。现在,Java是将异常代码和问题处理代码分离,提高阅读性.

9.1.1 Java的异常体系    

       因为,不正常的情况很多,描述不正常情况的类也很多,对很多问题类进行向上抽取,就形成了异常体系,分成两大类.

 

Throwable(可抛性)子类有:

             ――――>Exception:可处理 

             ――――>Error:一般不可处理(多数是JVM抛出的严重问题)

Exception Error的子类,都有一个共同特点,就是他们子类的后缀都是父类的类名:如ArrayIndexOutOfBoundsException, NoClassDefFoundError.

       9.1.2异常对象的抛出

      开发中,会遇到很多不正常的情况,一旦代码出现异常问题,就会导致程序的终止运行.为了避免异常问题的发生,通常需要在开发中对会发生的异常情况进行提前处理,或抛出由功能的调用者去处理.那么如何抛出异常呢:就使用到了关键字,throwthrows.

       异常的抛出,抛出的实际上就是描述异常情况的类的对象.

格式:throw new异常类(“描述异常的信息”)

如:class Demo{       void method(int []arr,int index){              if(index>arr.length-1||index<0)                     throw new ArrayIndexOutOfBoundsException("数组角标越界");//异常对象的抛出,              System.out.println(arr[index]);       }}class ExceptionDemo{       public static void main(String []args){              int []arr=new int[4];              new Demo().method(arr,5);//传入参数5,作为数组的角标.       }}


 

 

       9.1.3自定义异常类和异常的声明

Java本身已经提供了很多的异常类,供我们在开发过程中使用,当然,我们自己也可以定义异常类.

如果想让一个类成为异常类,那么这个在必须要继承异常体系,因为只有继承了Throwable类的才具有可抛性,才能被throw,throws操作.

如:class ExceptionDemo{       public void method(int []arr,int index)throws FuShuIndexException{//声明异常,这里为什么只要声明一个异常呢?              if(arr==null)                     throw new NullPointerException ("数组不存在");//抛出异常              if(index>arr.length-1)                     throw new ArrayIndexOutOfBoundsException("数组角标越界");//抛出异常              if(index<0)                     throw new FuShuIndexException("角标是负数!");//这一句话中抛出了自定义的异常类的对象.              System.out.println(arr[index]);       }}class FuShuIndexException extends Exception//自定义一个异常类,继承异常体系中的Exception子类.(也可以继承RuntimeException,就不需进行声明了){       FuShuIndexException(){}//定义无参数的构造函数       FuShuIndexException(String msg){super(msg);}//定义有参的构造函数} public class Demo{       public static void main(String[]args)throws FuShuIndexException{//主函数调用了有异常声明的方法method,没有捕捉也进行声明,由JVM处理.              int []arr=new int[4];//创建一个数组,长度为4              ExceptionDemo d=new ExceptionDemo();//创建ExceptionDemo类的对象              d.method(arr,-3);//调用ExceptionDemo类中的method()方法.       }}


 

 

问题一:为什么在ExceptionDemo类中的method方法中抛出了三个异常对象,如果不声明自定义的异常,编译就会失败,而不声明其他两个异常编译却可以通过?

       这是因为自定义异常类FuShuIndexException和其他两个异常类,分别继承了不同的异常父类的原因,自定义异常类继承了Exception,而其他两个异常类:NullPointerExceptionArrayIndexOutOfBoundsException继承了Exception的子类,RuntimeException类.查看API文档

java.lang.Object
 -> java.lang.Throwable
     -> java.lang.Exception
         -> java.lang.RuntimeException

那么继承Exception的异常类和继承RuntimException的异常类有什么区别?

       1,Exception及其子类,除了RuntimeException及其子类外,编译时会被检查,也称为受检查异常.

       2,RuntimeException及其子类,编译时不会被检查,运行时检查异常,也称为运行时异常.

但是,代码中无论是Exception,还是RuntimeException异常,只要在程序运行时发生异常,都会终止代码的执行.对于,继承Exception(除了RuntimeException及其子类)的异常类,必须要对其捕捉或声明,否则编译就会失败.而继承RuntimeException类的异常类,可以不捕捉或声明,编译都会通过.只是当该异常发生时,程序会终止运行.

所以,如果自定义异常类FuShuIndexException如果继承的是RuntimeException类,也就不需要进行声明了.一般在开发中,应避免RuntimeException异常的发生.这就是以上为什么必须要对自定义异常类进行捕捉或声明的原因.

       Exception异常的出现,因为在编译时期,可以针对性的处理.而RuntimeException异常问题的出现,一般在运行时期,无法让功能继续,运算也无法进行.这种问题一般由功能的调用者去处理.

 

问题二:Java中对异常的声明是什么意思.

       异常声明的目的是让调用者知道,调用此功能可能会出现的异常问题,为了让调用者去处理.

注意:throwthrows有区别

throw:定义在函数的内部,用于抛出异常的对象.如,以上代码.

throws:定义在函数的声明上,用于声明函数可能发生的异常情况,可以抛出多个异常,多个异常之间用“,”号隔开.

如:class ExceptionDemo{       public void method(int []arr,int index)throws FuShuIndexException,BigArrayIndexException{//这里必须声明两个异常,逗号隔开.              if(arr==null)                     throw new NullPointerException("数组不存在");              if(index>arr.length-1)                     throw new BigArrayIndexException("数组角标值大了");//抛出自定义异常类的对象              if(index<0)                     throw new FuShuIndexException("角标是负数!");//这一句话中抛出了自定义的异常类的对象.              System.out.println(arr[index]);       }}class FuShuIndexException extends Exception//自定义一个异常类,继承异常体系中的Exception子类.{       FuShuIndexException(){}//定义无参数的构造函数       FuShuIndexException(String msg){super(msg);}//定义有参的构造函数}class BigArrayIndexException extends Exception{       BigArrayIndexException(){}       BigArrayIndexException(String msg){super(msg);}}public class Demo{       public static void main(String[]args)throws FuShuIndexException,BigArrayIndexException{//              int []arr=new int[4];//创建一个数组,长度为4              ExceptionDemo d=new ExceptionDemo();//创建ExceptionDemo类的对象              d.method(arr,-3);//调用ExceptionDemo类中的method()方法.因为没有处理该方法的异常,所以在主函数上声明       }}


 

 

9.1.4 异常的捕捉

对于Exception异常及其子类来说,一旦异常被抛出都要进行捕捉或者声明,否则程序编译就会失败.

异常的声明,使用关键字throws,目的是告诉调用者,让调用者去处理.

而异常的捕捉,则是对异常的实际处理方式,可以保证程序发生异常后,依然能继续执行.

异常捕捉的关键字:try…catch…finally

格式:

try{

//需要被检测异常的代码;

}

catch(用于接收异常的类 变量){

       //处理异常的代码;

      ......

}

…//可以有多个catch

finally{

//一定会被执行的代码(除非在finally代码块之前执行System.exit(0));
}

注意:finally代码块,是在return语句前执行的.

如:public class Demo{       public static void main(String[]args){              try{                     throw new Exception();//抛出异常                     }              catch(Exception e){//接收异常                     System.out.println("A");//处理异常的代码                     return;//这里虽然有return语句,但是finally中的代码依然会执行,如果在这里执行此句代码,System.exit(0);则finally就不会被执行..              }              finally{//一定会被执行的代码.                     System.out.println("B");              }       }}//打印结果:A B


 

 

 

 

try,catch,finally三个关键字均不能单独使用,组合方式有:

1,try…catch…finally:检测并处理异常.

class ExceptionDemo{       void method()throws MyException{//声明异常              throw new MyException("自定义异常类");       }}class MyException extends Exception//自定义异常类.{       MyException(){}       MyException(String msg){super(msg);}}public class Demo{       public static void main(String[]args){              try{                     new ExceptionDemo().method();//需要被检测异常的代码              }              catch(Exception e){//接收异常类的对象,相当于Exception e=new MyException();多态特性.                     e.printStackTrace();//按照JVM默认的形式,打印结果.              }              finally{                     System.out.println("over");//最终会执行的代码块.              }       }}


 

 

2,try…catch(多个catch):检测处理异常,但没有finally代码块.

class ExceptionDemo{       public void method(int []arr,int index)throws FuShuIndexException,BigArrayIndexException{//这里必须声明两个异常,逗号隔开.              if(arr==null)                     throw new NullPointerException("数组不存在");//抛出空指针异常              if(index>arr.length-1)                     throw new BigArrayIndexException("数组角标值大了");//抛出自定义异常类的对象              if(index<0)                     throw new FuShuIndexException("角标是负数!");//这一句话中抛出了自定义的异常类的对象.              System.out.println(arr[index]);       }}class FuShuIndexException extends Exception//自定义一个异常类,继承异常体系中的Exception子类.{       FuShuIndexException(){}//定义无参数的构造函数       FuShuIndexException(String msg){super(msg);}//定义有参的构造函数}class BigArrayIndexException extends Exception//自定义一个异常类,继承异常体系中的Exception子类.{       BigArrayIndexException(){}       BigArrayIndexException(String msg){super(msg);}}public class Demo{       public static void main(String[]args){//              int []arr=new int[4];//创建一个数组,长度为4              ExceptionDemo d=new ExceptionDemo();//创建ExceptionDemo类的对象              try{d.method(arr,5);//调用ExceptionDemo类中的method()方法.并用try检测异常              }              catch(FuShuIndexException e){//接收自定义异常类                     System.out.println(e.getMessage());              }              catch(BigArrayIndexException e){//接收自定义异常类                     System.out.println(e.getMessage());              }              catch(NullPointerException e){//接收空指针异常                     System.out.println(e.getMessage());              }              catch(Exception e){//多个catch时,最大的父类异常类放在最下面.                     e.printStackTrace();              }                     }}


 

 

3,try…finally:只检测异常,不处理.

 

 

class ExceptionDemo{       public void method(int []arr,int index)throws FuShuIndexException,BigArrayIndexException{//这里必须声明两个异常,逗号隔开.              if(arr==null)                     throw new NullPointerException("数组不存在");//抛出空指针异常              if(index>arr.length-1)                     throw new BigArrayIndexException("数组角标值大了");//抛出自定义异常类的对象              if(index<0)                     throw new FuShuIndexException("角标是负数!");//这一句话中抛出了自定义的异常类的对象.              System.out.println(arr[index]);       }}class FuShuIndexException extends Exception//自定义一个异常类,继承异常体系中的Exception子类.{       FuShuIndexException(){}//定义无参数的构造函数       FuShuIndexException(String msg){super(msg);}//定义有参的构造函数}class BigArrayIndexException extends Exception//自定义一个异常类,继承异常体系中的Exception子类.{       BigArrayIndexException(){}       BigArrayIndexException(String msg){super(msg);}}public class Demo{       public static void main(String[]args)throws FuShuIndexException,BigArrayIndexException{//              int []arr=new int[4];//创建一个数组,长度为4              ExceptionDemo d=new ExceptionDemo();//创建ExceptionDemo类的对象              try{d.method(arr,5);//调用ExceptionDemo类中的method()方法.并用try检测异常              }              //因为代码中只try并没有catch处理,所以,调用method方法的主函数,还是要声明异常              finally{                     System.out.println("over");              }                     }}


 

注意:try检测到异常后,必须由catch捕捉处理或throws声明后,程序才能继续执行,否则程序中断.

          如果一个函数,声明多个异常,就需要用多个catch接收异常类的对象,要把最大的父类异常类放在最下面,否则,会编译失败.

 

总结异常处理的原则:

1,如果函数内部抛出了需要检测的异常,那么函数上必须要声明异常,有几个声明几个,否则,必须要try……catch异常,否则编译失败。

2,如果调用了声明异常的函数,那么要么try…..catch,要么声明异常,否则编译失败。

3,什么时候try…..catch,什么时候声明呢?

可以处理的异常,就try……catch,解决不了的就声明。

4,如果一个函数声明了多个异常,就用多个catch去接收并处理,有几个异常,就用几个catch,把接收最大的父类异常类,放在最下面。

 

 

 

 

 

---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
原创粉丝点击