黑马程序员——java基础----面向对象(四) 异常处理

来源:互联网 发布:淘宝买大玩家币能用吗 编辑:程序博客网 时间:2024/06/05 23:08
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
异常处理
1,什么是异常:
           异常就是程序中出现的问题或者是非正常的情况。
2,异常的由来:
           当我们在玩游戏的时候就会出现一些状况,我们俗称(漏洞)bug。而在程序中,漏洞是无处不在,即使我们认为程序中应该没有错误了,漏洞总会在某个时候就会冒出来,这给我们造成很多困扰。正因为这样,java提供了异常处理机制来协助我们避开可能的错误。
           因为有异常就证明出现问题了,问题也是现实生活中一个具体的事物,也可以通过java类的形式进行描述,并封装成对象。其实就是java对不正常情况进行描述的后的对象的体现。
简单的说:就是java把程序编译和运行时出现的问题进行描述后封装成异常类对象了。
3,异常的一些重要的继承架构
            Throwable
                 |---Error(严重的问题)
                        |---linkagError
                        |---ThreadDeath
                        |---VirtualMachineError
                         ...
                 |---Exception(非严重的问题)(编译时异常)
                        |---ClassNotFoundException
                        |---CloneNotSupportedException
                        |---IllegalAccessException
                         ...
                        |---RuntimeException(执行时异常)
                            |---ArithmeticException
                            |---ArrarStoreException
                            |---ClassCastException   
                             ... 
 特点:异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被throw和throws关键字所操作。 只有异常体系具备这个特点。
4,异常的处理:
           java提供了特有的语句进行处理。
try{
    需要被检测的代码(捕获)
}
catch(异常类 变量){
    处理异常的代码:(处理方式)
}
finally{
    一定会执行的语句(一般用于关闭资源)
}
5,多异常的处理
          (1)声明异常时,建议声明更为明确的异常,这样处理的可以更具体。
          (2)对方声明几个异常,就对应有几个catch块。如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
代码:
class Demo{int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现的问题。{   int [] arr = new int[a];//创建一个数组   System.out.println(arr[4]);//打印数组中第四个元素。   return a/b;//返回a除以b的值}}class ExceptionDemo2{public static void main(String[] args) {Demo d = new Demo();//创建Demo类对象try//检测异常代码{int x = d.div(4,0);//调用Demo类中的功能获取值    System.out.println("x="+x);//打印所获取的值}catch (ArithmeticException e)//处理异常代码{System.out.println(e.toString());//打印异常信息System.out.println("被零除啦");//异常输出}catch (ArrayIndexOutOfBoundsException e)//处理异常代码{System.out.println(e.toString());//打印异常信息System.out.println("角标越界拉");//异常输出}catch(Exception e){//父类异常      }System.out.println("over");//结束标记}}
6,自定义异常
              我们可以从Exception类或者它的子类派生一个新类,定义自己的异常。
代码:
class FuShuException extends Exception//自定义异常FuShuException继承Exception{        private int value;//定义一个整型变量FuShuException(){//无参数构造函数 super();//调用父类的无参数构造方法}    FuShuException(String msg,int value){//有参数构造函数   super(msg);//调用父类有参数构造方法,完成值传递   this.value = value;//传值}public int getValue(){//自己创建特有的异常方法      return value;}}class Demo{int div(int a,int b)throws FuShuException//抛出异常{   if(b<0)   throw new FuShuException("出现了除数是负数的情况----------/ by zero",b);//抛出异常对象,参数是错误的信息和输入的错误值。   return a/b;//返回值}}class ExceptionDemo3{public static void main(String[] args) {Demo d = new Demo();//创建一个Demo类对象try//检测异常代码{ int x = d.div(4,-9);//通过对象调用本类的功能,将运算结果给x。         System.out.println("x="+x);//打印x}catch (FuShuException e)//处理异常代码{System.out.println(e.toString());//打印异常信息//System.out.println("除数出现负数了");//异常信息System.out.println("错误的数字的是"+e.getValue());//打印输入错误的值。}System.out.println("over");//结束标记}}
7,throw和throws的区别
                  (1)throws使用在函数上,后面跟的是异常类,多个异常类用逗号隔开 。
                  (2)throw使用在函数内,后面跟的是异常类对象。
8,RuntimeException(运行时异常) 
                 (1)如果在函数内抛出异常,函数上可以不用声明,编译一样通过。
               (2)如果在函数上声明了该异常,调用者可以不用进行处理。编译一样通过。
 其实运行时异常,就是无法预测这个异常一定会发生,要看程序逻辑写的如何,因而不需要特别使用 try...catch或是在方法上使用throws声明也可以通过编译。
 例如:在使用数组时,并不一定要处理ArrayIndexOutOfBoundsException异常,因为只要程序逻辑写得正确,这个异常就不会发生。
代码:
class Demo{   int div(int a,int b)//因为函数上没有声明异常,所以调用者不知道此功能会发生异常,但是编译还是没问题的这就是RuntimeException   {   if(b==0)   throw new ArithmeticException("被零除啦");//函数内部抛出一个异常      return a/b;      }}class ExceptionDemo4{public static void main(String[] args) {                 Demo d = new Demo();//创建Demo类对象 int x = d.div(4,0);//去值//由于函数上没有声明该异常所以调用者根本就不知道有没有异常。 System.out.println("x="+x);//打印x值System.out.println("over");//结束标记}}
对于异常分为两种:
              (1)编译时被检测异常(即可控异常):可以理解为程序执行前所发生的异常,即可以预想到的。
 例如:使用到BufferReader的ReadLine()时,有可能会发IOException异常,要么try..catch,要么在方法上使用throws表示由调用该方法的调用者来处理。
 注意:当发生被检测异常时,thorw和throws的使用
              如果一个功能内部出现了异常,要么内部自己try..catch处理,要么内部使用throw抛出异常对象并在函数上使用throws声明给调用者处理。 当发生不被检测异常时,功能内部抛出异常对象,函数上不用声明,完全交由虚拟机。   
             (2)编译时不被检测的异常(即不可控异常):程序执行时异常,即程序执行过程中所会出现的错误,有的程序员能想到,有的不一定能想到。
例如:在使用数组时,并不一定要处理ArrayIndexOutOfBoundsException异常,    因为只要程序逻辑写得正确,这个异常就不会发生。
9,异常实例
           老师用电脑上课
 上课中会出现的问题: 电脑蓝屏(电脑重启),电脑冒烟(课时无法继续)
注意:当遇到一些问题解决不了的时候,就要向外抛,但是,抛出问题之前要考虑,抛什么?对方能不能解决了?如果解决不了,那么即使你捕获到这个异常,在catch中也是处理不了的,那么索性在catch中就不处理这个异常,把这个异常抛出去,但是,抛出的异常一定要是对方能处理的异常,不一定是捕获的异常!!(非常关键)
自定义异常代码:
class LanPingException extends Exception//自定义蓝屏异常{    LanPingException(String message){super(message);//调用父类的构造方法,来完成传递发生异常的信息。}}class MaoYanException extends Exception//自定义冒烟异常{    MaoYanException(String message){   super(message);//调用父类的构造方法,来完成传递发生异常的信息。}}class NoPlanException extends Exception//自定义课时无法继续异常{     NoPlanException(String message){   super(message);//调用父类的构造方法,来完成传递发生异常的信息。 }}
电脑类
class Computer//电脑类{  private int state=3;//临界值,1,正常 2,蓝屏 3,冒烟        //电脑运行方法public void run()throws LanPingException,MaoYanException//抛出异常类{       if(state==2)//蓝屏  throw new LanPingException("蓝屏了");//抛出蓝屏异常对象  if(state==3)  throw new MaoYanException("冒烟了");//抛出冒烟异常对象  System.out.println("电脑运行");//临界值为1时,电脑正常运行。}public void reset()//电脑类中特有的方法,重启。{ state = 1;//临界值1  System.out.println("电脑重启");}}
老师类
class Teacher//老师类{   private Computer cmpt;//电脑对象private String name;//老师姓名    Teacher(String name){this.name=name;//传值cmpt = new Computer();//创建电脑类对象   }        //老师讲课方法public void prelect()throws NoPlanException//抛出课时无法继续异常。{try{cmpt.run();//调用电脑的运行方法}catch(LanPingException e)//处理蓝屏{cmpt.reset();//电脑重启}catch(MaoYanException e)//处理冒烟{   test();//学生做练习throw new NoPlanException("课时无法继续"+e.getMessage());//抛出异常对象/*为什么要抛出课时无法完成异常?                          因为当出现冒烟异常时,老师也处理不了,而如果要是抛出冒烟异常,调用者只负责处理                         老师讲课的问题,也处理不了冒烟,所以当发生冒烟异常时,要抛出课时无法完成异常,                         这样调用者可以处理。                        */ }      System.out.println("讲课");}public void test()//练习方法{  System.out.println("练习");}}
调用者类
class  ExceptionTest//调用者类public static void main(String[] args) {Teacher  t= new Teacher("老师");//创建老师对象        try//检测异常        {t.prelect();//调用老师讲课方法        }        catch (NoPlanException e)//处理异常        { System.out.println(e.toString());//打印异常信息System.out.println("换老师或者放假");//解决办法        }}}
10,异常在子父类中覆盖的体现:
                (1)子类在覆盖父类方法时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类。
                (2)如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
                (3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。 如果子类方法发生了异常,就必须要进行try处理,绝对不能抛。
代码:
class AException extends Exception//A异常继承Exception{}class BException extends AException//B异常继承A异常{}class CException extends Exception//C异常继承Exception{}//父类class Fu{void show()throws BException//抛出B异常{}//        void show()throws AException//抛出A异常//{////}}//子类继承父类class zi extends Fu{void show()throws BException//只能抛出 B 异常,即:由于BException没有子类,所以抛出父类所抛出的异常。{}//        void show()throws AException//抛出A,B异常,即:父类异常有子类,所有抛出父类的异常和父类异常子类都可以。//{////}}







0 0
原创粉丝点击