彻底明白JAVA的异常处理 -3

原创 2003年11月23日 19:17:00

四.继承中异常

1.         关于构造函数中的异常

1.1          构造函数中的异常规则

某个derived class构造函数的异常规格接口“可以比其所调用的父类的构造函数的异常规格接口宽,但决不能变窄。

1)        derived class的构造函数必须在自己的异常规格中声明所有base class构造函数的异常规格中所声明的异常。

2)        derived class的构造函数的异常规格中还可以声明新的异常,即声明在base class构造函数的异常规格中没有声明的异常。

1.2          原因

当在产生一个derived class的对象时,会在derived class的构造函数中调用base class的构造函数(初始化过程请见第6章),所以在derived class的构造函数中可能会抛出base class构造函数的异常规格中声明的异常,因此要在derived class的异常规格中声明base class构造函数的异常规格中声明的异常。

**:如果调用的函数的异常规格中声明了异常,那么在调用该函数的时候要捕捉它的异常规格中声明的异常。但在derived class构造函数中却无法捕捉其base class构造函数所掷出的异常。

2.         关于非构造函数的异常规则

2.1          某个函数的异常规格接口“在继承和重载中可以变窄,但决不能变宽

要覆写base class的函数时,如果被覆写函数(base class中的函数)的异常规格中声明了异常,那么覆写函数(derived class中覆写了base class中的函数的那个函数)的异常规格中可以声明(1)与被覆写函数完全相同的异常;(2)被覆写函数异常规格中的部分异常或其子类异常;(3)不声明异常规格。

2.2          原因

这么做是为了满足“能处理被覆写函数的代码,不用做任何修改就能处理覆写函数的代码”的原则。

如果覆写函数的异常规格中声明了在被覆写函数的异常规格中不存在的异常,那么能处理被覆写函数的代码就不能处理覆写函数,因为没有捕捉覆写函数中不存在于被覆写函数中的异常声明。

              import java.sql.SQLException;

class BaseClass{

                  public void f(){}

}

class DerivedClass1 extends BaseClass{

                  //public void f() throws SQLException {} (1<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

                  public void f() {} //2

}

public class Test{  

                  public static void f(BaseClass bc) { bc.f(); }

                     /* (3

public static void f(BaseClass bc) {

                            try{

                                   bc.f();

                            }

                            catch(SQLException ex){}

}

*/

                  public static void main(String[] args){

                      BaseClass bc = new BaseClass();

                      f(bc);

                      DerivedClass1 dc = new DerivedClass1();

                      f(bc);

                  }

}

如果允许“异常接口“变宽,我们看看上面代码会出现什么结果。首先,我们可以将代码(1)的注释去掉,并注释掉代码(2)。由于BaseClass class中的被覆写f()函数没有声明异常规格,而代码(1)中覆写f()函数声明了,那么Test class中的f(BaseClass bc)虽然能处理被覆写f()函数的调用,但不能处理覆写f()函数的调用,因为代码覆写f()函数声明了异常规格,而f(BaseClass bc)没有进行捕捉。那么为了处理覆写f()函数,我们还要编写代码(3)那样的处理函数。

2.3          产生对象的异常规则

在产生一个对象时,捕捉的是产生对象时所调用的构造函数中所声明的异常。

2.4          函数调用时的异常规则

1)        当把一个对象向上转型为它的base class时,并通过转型后的reference进行函数调用时,我们要捕捉的是其base class的异常声明。

2)        当用对象的原始类型来调用函数时,只需捕捉所调用的覆写函数的异常

2.5          继承中的异常规则的一个实例

import java.lang.Exception;

class BaseException extends Exception {}

class Derived1Exception extends BaseException {}

class Derived2Exception extends BaseException {}

class Derived11Exception extends Derived1Exception {}

class BaseClass{

    BaseClass() throws Derived1Exception {}

    BaseClass(int i) throws BaseException {}

    BaseClass(int i, int j) {}

    //在覆写f()时不能声明异常规格

    public void f() {}

//在覆写g()时可以不声明异常或声明BaseException异常或声明

//BaseException异常的子类

    public void g() throws BaseException {}

    //在覆写u()时可以不声明异常

    public void u() throws Derived1Exception, Derived2Exception {}

}

class DerivedClass1 extends BaseClass{

    //base class构造函数中声明了异常的处理方法

    //声明与base class构造函数中的异常完全相同的异常

    DerivedClass1(int i) throws Derived1Exception {}

    //声明base class构造函数中的异常的父类异常

    DerivedClass1() throws BaseException {}   

    //声明base class构造函数中的异常和新的异常

    DerivedClass1(String s) throws Derived1Exception,  Derived2Exception{}

    //声明base class构造函数中的异常父类异常和新的异常

    DerivedClass1(String s, int i) throws BaseException,  Derived2Exception{}

    DerivedClass1(int i, int j) { super(i, j); }

    //注意下面这两句

    DerivedClass1(int i, String s) throws BaseException { super(i); }

    //DerivedClass1(int i, String s) throws Derived1Exception { super(i);}

    public void f() {}

    //下面覆写g()的几种方式

    //不声明

    //public void g() {}

    //public void g() throws BaseException {} 声明完全相同

    //声明子类异常

public void g() throws Derived1Exception {}

//声明子类异常

    //public void g() throws Derived1Exception, Derived11Exception {} 

    //下面覆写u()的几种方式

    //public void u() {} 不声明

    //public void u() throws Derived11Exception {} 声明部分异常的异常

    //public void u() throws Derived1Exception {} 声明部分异常

    //声明完全相同

//public void u() throws Derived1Exception, Derived2Exception {} 

//声明子类异常

    //public void u() throws Derived1Exception, Derived11Exception {} 

}

public class Test{

    public static void main(String[] args){

        //捕捉的是相应的构造函数的异常

        try{

            BaseClass bc1 = new DerivedClass1();

        }

        catch(BaseException be) {}

        try{

            BaseClass bc2 = new DerivedClass1("bc2");

        }

        catch(Derived1Exception be1) {}

        catch(Derived2Exception be2) {}

        //通过向上转型来调用函数

        BaseClass bc3 = new DerivedClass1(1, 1);

        /*捕捉的是父类中被覆写的函数的异常,而这里捕捉的是子类中

         * 被覆写的函数的异常,所以编译错误

        try{

            bc3.g();

        }

        catch(Derived1Exception be) {}

        */

        //捕捉了被覆写函数的异常,是正确的

        try{

            bc3.g();

        }

        catch(BaseException be) {}

        //用对象的原始类型来调用函数

        DerivedClass1 dc1 = new DerivedClass1(1, 1);

        //只需捕捉所调用的覆写函数的异常

        try{

            dc1.g();

        }

        catch(Derived1Exception be) {}

    }

}

彻底明白JAVA的异常处理-1

一.基本异常1.         抛出异常的原理1)        像产生一个Java对象那样在heap上以new产生一个异常对象。2)        停止目前的执行路线,将上述那个异常对象的refe...
  • Nepalon
  • Nepalon
  • 2003年11月23日 19:18
  • 1423

彻底明白JAVA的异常处理-2

2.         异常规格(exception specification)1)        在函数定义时可以声明异常规格。如果一个函数在异常规格中声明了non-RuntimeException...
  • Nepalon
  • Nepalon
  • 2003年11月23日 19:17
  • 1439

java值传递彻底明白~

时间: 2004-4-06 13:18:27    标题: 一个绝对害了不少人的Java技术问题! 我不记得自己是怎么学到的,但是我相信绝大部分从事java学习Java的人都一直这么以为一个小的技术问...
  • faintbear
  • faintbear
  • 2004年11月29日 16:24
  • 13967

彻底明白Java的多线程

彻底明白Java的多线程-线程间的通信(1) 作者:恒善喜 来源:不详 (2006-06-02 14:51:45)   线程间的通信1. 线程的几种状态线程有四种状态,任何一个线程肯定处于这四种状态中...
  • hehuii
  • hehuii
  • 2008年04月07日 10:38
  • 1340

彻底明白Android中AIDL及其使用

对于AIDL不少人的理解是,AIDL可以完成应用之间的通讯,那么Android推出Messager不就是完成应用之间通讯的嘛,那么AIDL和Messager有什么不同。多点时间研究一下,分享一下我的结...
  • wangduanqing5945
  • wangduanqing5945
  • 2014年06月27日 11:36
  • 1292

彻底掌握JAVA的异常处理

异常:阻止当前方法或作用域继续执行的问题。特别需要注意的,程序抛出异常,不管这个异常是否严重,都必须进行处理,决不能有运算结果不出错就是正常的想法。 先来看看异常有哪些类: Throwable类是...
  • springcsc1982
  • springcsc1982
  • 2013年04月17日 16:14
  • 910

一句话彻底明白java乱码问题

相信java的中文编解码问题是让许多java开发者头疼的问题,一旦遇到坑就会在GBK和UTF-8之间纠结。 我有两次痛苦的经历,一次是和另一个公司的C++平台传数据,调接口的时候因为中文乱码耽误了好多...
  • hotthought
  • hotthought
  • 2015年12月30日 15:24
  • 1507

彻底搞明白java synchronized

本文来着点击打开链接     http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 1、synchronized关键...
  • zgliang88
  • zgliang88
  • 2014年01月14日 21:07
  • 345

红黑树----第四篇:一步一图一代码,一定要让你真正彻底明白红黑树 --- 很好

一步一图一代码,一定要让你真正彻底明白红黑树   作者:July   二零一一年一月九日 ----------------------------- 本文参考: I、  The Art of Com...
  • JK198310
  • JK198310
  • 2013年08月12日 16:05
  • 1891

彻底明白Java的IO系统(zt)

一. Input和Output1. stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。在Java的IO中,所有的stream(包括Input和Out stream)都包括...
  • yu_shi_bin
  • yu_shi_bin
  • 2004年06月24日 10:48
  • 528
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:彻底明白JAVA的异常处理 -3
举报原因:
原因补充:

(最多只允许输入30个字)