(4) - 异常(图)

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------

 

个人学习后归纳的知识点,利于整体记忆。

1、  异常概述

(1) 异常(exception):是指程序运行时发生的问题事件,该事件可以中断程序指令的正常执行流程。如除数若为0,就是一个异常。

(2) 类结构

         Throwable

               |--Error

               |--Exception

                      |--RuntimeException

Throwable类:java语言所有错误或异常的的超类,只有是它的子类才能具有异常抛出能力,即可抛性。

 

Error类:有java虚拟机生成并抛出,包括动态连接失败,虚拟机错误等,java程序无法对此错误进行处理。

 

Exception类:一般程序可预知的问题,其长生的异常可能会带来预计中的后果,因此java编译器要求java程序必须捕获或者声明抛出所有非运行时异常。

RuntimeException类:java虚拟机运行时生成的异常,如被0除的系统错误,数组下标越界等,其产生比较频繁,处理麻烦,对程序的可读性和运行影响太大,因此由系统检测,开发者可不做处理,系统将他们交给缺省的异常处理。(必要时,可进行处理)

由上可知:对于异常分两种,一种是编译时要检测的异常(Exception),另一种是编译时不被检测的异常,即运行时异常(RuntimeException及其子类)

 

2、  异常处理机制

①    当java程序运行时出现问题时,系统会自动检测到改错误,并立即生成一个相应的异常对象。

②    把该异常对象提交给java虚拟机。

③    虚拟机会先找对应的处理代码来处理该异常,如果没有找到,程序终止。

④    当然程序员可以自己捕捉可能出现的异常,编写代码处理相应的异常。

简单说呢,就是java把常见错误处理封装了,当有异常报告时,由系统进行接管,我们向上抛就行了,一级一级往上抛,最后给虚拟机。当然建议自己捕捉处理。

这个机制的一个好处,函数能将自己会出现的异常跟调用者进行交流,告知调用者进行处理。

 

3、  异常捕获处理代码格式

try{
      需要检测的代码; 
    }
    catch(异常类 变量){ 
       异常处理代码; 
     }
    //多个catch块
       ... 
     finally{
        一定会执行的代码;//释放资源等

      }


注意点:

(1)try不能单独存在,没有catch块就代表捕获的异常没有做处理。

(2) finally中的代码一定会执行,即是catch块中含有return语句也依旧会执行,但是在finally前面执行了System.exit(0);程序都终止了则不会在执行了。

 

4、异常处理的抛出处理及throw与throws

当一个函数有预知异常时,而又不进行捕获处理,应当将异常声明并抛出给调用者,告知调用者处理。

如下:

class A

{
    //通过throws声明该函数可能会出现问题,可定义具体Exception
    int div(int a, int b)throws Exception
    {
     return a/b;//有可能被0除
     }
}
public class Test
{
    public static void main(String[] args) throws Exception
    {
        A a = new A();
        //该函数以声明异常,需处理,这里简单的继续抛出
        //一般建议try补捉处理
        int x = a.div(4, 1); 
     }
}


throw和throws的区别:

                  throw定义在函数内,用于抛出异常对象。如throw new Exception();。

                  throws定义在函数上,用于抛出异常类,刻意抛出多个,用逗号隔开。

当函数内容有throws抛出异常对象,并未进行try处理,那么必须要在函数上声明,否则编译失败。如上面的例子没用try捕捉在main函数上继续抛出。

注意:RuntimeException除外,也就说,函数内如果抛出的RuntimeException异常,函数上可以不声明。

下面是throw用法

class A
{
     int div(int a, int b) throws Exception
     {
         if(b==0)//非RuntimeException需要抛出异常
             throw new Exception();//throw用法,或写在某个try的catch块中
         return a/b;//有可能被0除
    }
     int run()//由于是RuntimeException不用声明抛出
     {
         int k =0;
         if(k == 0)//throw RuntimeException的对象
             throw new RuntimeException("除数不能为0"); 
         return 4/k;
     }
}
public class Test
{
    public static void main(String[] args)  throws Exception
   {
     A a = new A();
     int x = a.div(4, b);
    }
}


RuntimeException类是会使程序终止的异常,同样是创建对象希望的,不想进行处理,没有抛出的的必要。

 

5、多异常处理

在异常的抛出时,会出现多个异常,可以在函数上抛出多异常   如下:

class A
{
//多异常抛出
     int div(int a, int b) throws ArrayIndexOutOfBoundsException,ArithmeticException
     {
         int [] arr ={1};
         int k = arr[4];
         return a/b;//有可能被0除
     }
}
public class Test
{
    public static void main(String[] args)//try后不用上抛了
    {
     A a = new A();
     try
     {
         int x = a.div(4, 0);
     }
     //抛出几个异常就处理几个
     catch(ArithmeticException e)
     {
         System.out.println("被0除了!");
     }
     catch(ArrayIndexOutOfBoundsException e)
     {
         System.out.println("数组角标越界");
     }
     //异常子类的父类异常cathc得放在子类异常的后面
     catch(Exception e)
     {
         System.out.println("父类异常!下 放");
     }
}
}


多异常的处理特点:

(1) 异常声明时最好声明具体的异常,这样能具体处理。

(2) 声明中抛出几个异常,就要catch处理几个。

(3) 如果多个catch块中的异常带有继承关系,父类的异常要放在最下面,如果放在前面,它的处理包括了子类的处理,后面在处理子类异常就多余了。

 

6、自定义异常

在使用时,会出现java没有包含的异常类别,这时开发者可以自定义有针对性的自己的异常类。

class FushuException extends Exception
{
    FushuException(String msg)
    {
     super(msg);//在父类Throwable中有接受自定义信息的构造函数
     }
}
class A 
{
     int div(int a, int b) throws FushuException
     {   
         if(b<0)//假设要求不能出现负数
             throw new FushuException("出现了负数!");
         return a/b;
     }
}
public class Test
{
    public static void main(String[] args)
    {
     A a = new A();
     try{
         int x = a.div(4, -1);
     } catch (FushuException e)
     {
         System.out.println(e.toString());
     }
}
}


自定义异常要求:子类需继承Throwsble,才具有可抛性。

 

7、  类继承时异常覆盖特点

特点:

(1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。

(2)如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。

即,父类含a、b、c、d、e异常那么子类可抛异常为其子集{a、b、c、d},{…..}等

(3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常。就必须要进行try处理,绝对不能抛。

/*
 * Exception
 *    |--AException
 *          |--BException
 *    |--CException
*/
class AException extends Exception
{
}
class BException extends AException
{
}
class CException extends Exception
{
}
class Fu
{
   //只抛了AException,但包含子类BException
   void show() throws AException
   {
   }
}
class Zi extends Fu
{
    //不能抛出CException,因为在Fu中没有
    void show() throws AException,BException
   {
     //真发生CException异常,就只能try不能抛
     try
     {
         see();//含CException异常
     }
    catch(CException e)
     {}
}
void see()throws CException{}
}

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值