小小笔记

  DonewsBlog  |  Donews首页  |  Donews社区  |  Donews邮箱  |  我的首页  |  联系作者  |  聚合   |  登录
  129篇文章 :: 0篇收藏:: 123篇评论:: 1个Trackbacks

公告

hoho

文章

收藏

相册

c/c++链接

e书下载

存档


正在读取评论……


Java之异常处理(Exception)

参考:TIJ

最近由于项目的需要,为了写一个稳健的系统,花了将近一天的时间重新学些了javaException机制.

因为的Java的主要目标就是发展可供他人使用的程序组件,如果想要构筑一个稳固的系统,每一个组件就必须都要强固才行.

Java的异常处理语言格式

try

{

  //可能产生异常的代码

}

catch(ExceptionType1 et)

{

   //处理这种异常

}

catch(ExceptionType2 et)

{

   //处理这种异常

}

//etc….

finally

{

   //一定会执行的动作,经常用来进行一些清理工作,不一定非要写

}

编写自己的异常类

package javaexception;

//演示了如何书写自己的异常

class MyException2 extends Exception

{

  private int i;

  public MyException2()

  {

  }

  public MyException2( String msg)

  {

    super(msg);

  }

  public MyException2(String msg,int j)

  {

    super(msg);

    i=j;

  }

  public int returnInteger()

  {

    return i;

  }

}

class ExtraFeatures

{

  public void f() throws MyException2

  {

    System.out.println("Throwing MyException2 from f()");

    throw new MyException2();

  }

  public void g() throws MyException2

  {

    System.out.println("Throwing MyException2 from g()");

    throw new MyException2("orginated in g()");

  }

  public void h() throws MyException2

  {

    System.out.println("Throwing MyException from h()");

    throw new MyException2("originated from h()",23);

  }

  public static void main(String [] args)

  {

    ExtraFeatures ef = new ExtraFeatures();

    try

    {

      ef.f();

    }

    catch(MyException2 e)

    {

      e.printStackTrace(System.err);

    }

    try

    {

      ef.g();

    }

    catch(MyException2 e)

    {

      e.printStackTrace(System.err);

    }

    try

    {

      ef.h();

    }

    catch(MyException2 e)

    {

      e.printStackTrace(System.err);

      System.out.println("e.returnInteger()="+e.returnInteger());

    }

  }

}

如何捕捉所有的异常

由于所有异常的基本型别均为Exception(异常的基本型别并非只是这一个,但是将Exception视为最终根本,对于所有的编程行为都是中肯的)捕捉所有的异常.

catch(Exception e)

{

  System.out.println(“Caught an exception”);

}

应该将其置于所有的处理程序的最末端,以免抢去其后的所有的异常处理函数的机会.

异常中函数的使用方法演示

package javaexception;

//此例用来演示Exception的各种method如何运用

class ExceptionMethods

{

  public static void main(String [] args)

  {

    try

    {

      throw new Exception("This is a Exception");

    }

    catch(Exception e)

    {

      System.err.println("Caught Exception");

      System.err.println("e.getMessage"+ e.getMessage());

      System.err.println("e.getLocalizedMessage" + e.getLocalizedMessage());

      /*

      Exception toString函数

             public String toString() {

               String s = getClass().getName();//获取classname

               String message = getLocalizedMessage();

               return (message != null) ? (s + ": " + message) : s;

             }

      */

      System.err.println("e.toString " + e.toString());

      System.out.println("e.printStackTrac)()");

      e.printStackTrace(System.err);

    }

  }

}

重掷异常

有时候你需要重掷异常,将异常重新掷出,会将该异常移动到另一个更高层的context的处理函数去.同一个try block

内的后续其他的catch子句则被忽略不计.此外,其异常的所有内容就会保留,因此上层context内的异常处理函数便会对此异常进行处理.

如果你只是单纯的掷出当前捕捉到的异常,那么使用printStackTrace函数印出的消息便会相应与异常的起始源头,而非异常的重新掷出点,如果你想要设立新的StackTrace信息,你可以是使用函数fillInStackTrace(),它会将目前的stack信息填入旧的异常类内,然后返回对象.

 

 

package javaexception

class OneException extends Exception {

  public OneException(String s) { super(s); }

}

 

 

class TwoException extends Exception {

  public TwoException(String s) { super(s); }

}

 

 

public class RethrowNew {

  public static void f() throws OneException {

    System.out.println(

      "originating the exception in f()");

    throw new OneException("thrown from f()");

  }

  public static void main(String[] args)

  throws TwoException {

    try {

      f();

    } catch(OneException e) {

      System.err.println(

        "Caught in main, e.printStackTrace()");

      e.printStackTrace(System.err);

      throw new TwoException("from main()");

    }

  }

} ///:~

异常的局限性

当你override某个函数时,只能够掷出它在base class 中明白列出(即列于异常规格中)的异常.具体一点就是:在派生类的

与基类相对应的函数中,异常的个数要少于或者等于基类所掷异常的个数,或者是基类所掷异常的子类.这是一个很好的限制,因为这意味着可在基类运行的程序代码(包括异常)都能自动在所有衍生的class objects上身上运行,这是基本的oop观念.

下面给出一个实例

package javaexception;

 

 

class BaseballException

    extends Exception

{}

 

 

class Foul

    extends BaseballException

{}

 

 

class Strike

    extends BaseballException

{}

 

 

abstract class Inning

{

  Inning() throws BaseballException

  {

    System.out.println("Inning constructor");

  }

 

 

  void event() throws BaseballException

  {

    // Doesn't actually have to throw anything

  }

 

 

 abstract void atBat() throws Strike, Foul;

 

 

  {

    System.out.println("Inning class atBat");

  }

 

 

  void walk()

  {} // Throws nothing

 

 

}

 

 

class StormException

    extends Exception

{}

 

 

class RainedOut

    extends StormException

{}

 

 

class PopFoul

    extends Foul

{}

 

 

interface Storm

{

  void event() throws RainedOut;

 

 

  void rainHard() throws RainedOut;

}

 

 

public class StormyInning

    extends Inning implements Storm

{

  // OK to add new exceptions for

  // constructors, but you must deal

  // with the base constructor exceptions:

  StormyInning() throws RainedOut,

      BaseballException

  {

    System.out.println("StormyInning constructor");

  }

 

 

  StormyInning(String s) throws Foul,

      BaseballException

  {}

 

 

  // Regular methods must conform to base class:

  //!void walk() throws PopFoul {} //Compile error

  // Interface CANNOT add exceptions to existing

  // methods from the base class:

//! public void event() throws RainedOut {}

  // If the method doesn't already exist in the

  // base class, the exception is OK:

  public void rainHard() throws RainedOut

  {}

 

 

  // You can choose to not throw any exceptions,

  // even if base version does:

   public void event()

  {}

 

 

  // Overridden methods can throw

  // inherited exceptions:

  void atBat() throws PopFoul

  {

    System.out.println("StormyInning class atBat");

  }

 

 

  public static void main(String[] args)

  {

    try

    {

      StormyInning si = new StormyInning();

      si.atBat();

    }

    catch (PopFoul e)

    {

      System.err.println("Pop foul");

    }

    catch (RainedOut e)

    {

      System.err.println("Rained out");

    }

    catch (BaseballException e)

    {

      System.err.println("Generic error");

    }

    // Strike not thrown in derived version.

    try

    {

      // What happens if you upcast?

      Inning i = new StormyInning();

      i.atBat();

      // You must catch the exceptions from the

      // base-class version of the method:

    }

    catch (Strike e)

    {

      System.err.println("Strike");

    }

    catch (Foul e)

    {

      System.err.println("Foul");

    }

    catch (RainedOut e)

    {

      System.err.println("Rained out");

    }

    catch (BaseballException e)

    {

      System.err.println(

          "Generic baseball exception");

    }

  }

} ///:~

程序的结果不好理解(没有整明白)

//应该先调用构造函数呀,为什么先是atBat?

Inning class atBat

Inning constructor

StormyInning constructor

StormyInning class atBat

 

 

Inning class atBat

Inning constructor

StormyInning constructor

StormyInning class atBat

下面谈谈异常规则的构造思想:

虽然异常规格在继承过程中有编译器强迫施行,但是异常规格并非函数型别的一部分.函数型别仅有其名称和引数(个数和型别)组成,即你无法只靠异常规格的差异进行重载.此外对函数而言,base class 版本既有的异常规格并不意味着必然发生于derived class 版本上.这和继承规则有着极大的不同.换个方式来看,某个函数的异常规格接口在继承和override的过程中可能变窄,不可能变宽.而这恰好和class接口在继承过程中规则相反.

对于构造函数不在此列,由于构造函数不属于override,其异常规格是越来越宽的.



Trackback: http://tb.donews.net/TrackBack.aspx?PostId=571339


[点击此处收藏本文]  发表于2005年09月28日 11:08 PM




正在读取评论……

发表评论

大名:
网址:
验证码
评论