赛迪网 > IT技术 Java > 技术动态
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

JAVA基础:面向对象的例外处理

发布时间:2006.10.02 04:59     来源:赛迪网论坛    作者:

什 么 是 例 外 、 例 外 处 理

    例 外 就 是 在 正 常 情 况 以 外 的 事 件 。 Java 之 中 的
例 外 是 指 程 序 运 行 中 发 生 的 异 常 事 件 , 这 些 异 常事 件 将 阻 止 程 序 的 正 常 运
行 。 比 如 出 现 了 数 组 越 界 、 用户 输 入 错 误 等 等 。 而 顾 名 思 义 , 例 外 处 理 就
是 对 这 些 例外 进 行 处 理 。

    所 有 的 高 级 计 算 机 编 程 语 言 里 都 有 判断 是 否 出 现
了 例 外 的 语 句 , 每 个 好 的 计 算 机 程 序 都 会 有对 例 外 进 行 处 理 的 程 序 段 。 只
不 过 在 不 同 的 计 算 机 编 程语 言 里 面 , 对 例 外 的 称 呼 不 同 , 例 如 有 的 语 言 里
所 讲 的错 误 处 理 , 其 实 就 等 同 于 Java 里 面 的 例 外 处 理 。 这 就 像诸 葛 亮 先 生
有 两 个 名 字 , 孔 明 是 他 诸 葛 亮 也 是 他 , 还 有人 称 呼 他 为 诸 葛 先 生 … … , 只
是 称 呼 不 同 罢 了 , 意 义 是一 样 的 。

抛 弃 之

    在 许 多 高 级 语 言 中 都 是 通 过 使 用 if 语句 来 判 断 是
否 出 现 了 例 外 , 并 进 行 处 理 的 。 Java 作 为 一个 完 全 基 于 面 向 对 象 的 语 言
, 例 外 处 理 也 是 采 用 面 向 对象 的 方 法 。 在 一 个 方 法 的 运 行 过 程 中 如 果 发 生
了 例 外 ,则 这 个 方 法 将 生 成 一 个 代 表 该 例 外 的 对 象 , 并 把 它 提 交给 正 在 运
行 这 个 方 法 的 系 统 。 我 们 把 这 个 过 程 称 为 抛 弃一 个 例 外 。

    就 像 抛 弃 这 个 球 一 样 , 把 它 给 抛 掉 了。 抛 弃 一 个
例 外 的 过 程 就 和 我 们 平 时 工 作 中 碰 到 了 特 殊情 况 无 法 解 决 , 需 要 写 一 份 报
告 交 把 这 个 棘 手 的 问 题 上报 上 级 主 管 部 门 一 样 。

捕 获 之

    系 统 在 运 行 的 时 候 查 找 处 理 提 交 给 它的 例 外 的 方
法 , 这 个 过 程 称 为 捕 获 一 个 例 外 。 这 就 和 法官 判 案 时 查 找 相 应 的 法 律 条 文
的 过 程 是 一 样 的 。

优 越 性

    1. 利 用 以 上 这 些 方 法 处 理 例 外 , 使 得例 外 处 理 的
程 序 代 码 与 普 通 的 程 序 代 码 不 再 混 为 一 体 ,减 少 了 编 程 序 的 工 作 量 , 同 时
也 增 加 了 程 序 可 读 性 。

    2. 利 用 面 向 对 象 的 方 法 来 处 理 例 外 ,可 以 对 各 种
不 同 的 例 外 事 件 进 行 分 类 , 然 后 再 处 理 之 ,从 而 具 有 了 良 好 的 接 口 和 层 次
性 。

    3. 利 用 类 的 层 次 性 既 可 以 区 分 不 同 的例 外 分 别 处
理 , 也 可 以 把 具 有 相 同 父 类 的 多 个 例 外 统 一处 理 , 具 有 相 当 的 灵 活 性 。

    由 以 上 几 点 可 知 , Java 的 这 种 面 向 对 象的 例 外 处
理 机 制 为 那 些 具 有 动 态 运 行 特 性 的 复 杂 程 序 提供 了 强 有 力 的 控 制 方 式 。

    以 上 这 些 优 越 性 背 下 来 就 可 以 了 , 到时 候 可 以 用
来 在 孩 儿 们 面 前 炫 耀 一 下 自 己 的 知 识 渊 博 。

与 例 外 处 理 相 关 的 类

    用 面 向 对 象 的 方 法 来 进 行 例 外 处 理 首先 必 须 建 立
类 的 层 次 。 如 图 20.1 所 示 , 类 Throwable 是 最 顶层 的 , 只 有 它 的 子 类 才
可 以 作 为 一 个 例 外 被 抛 弃 。

运 行 时 与 非 运 行 时 例 外 

    Java 有 运 行 时 例 外 和 非 运 行 时 例 外 之 分。

    所 谓 运 行 时 例 外 就 是 由 系 统 在 Java 程 序运 行 的 过
程 中 检 测 到 的 例 外 , 例 如 除 零 溢 出 ( 除 数 为 零导 致 的 错 误 ) 、 数 组 越 界 等
。 由 于 它 们 可 能 在 程 序 的 任何 位 置 发 生 , 而 且 谁 也 无 法 在 程 序 运 行 以 前 计
算 出 它 们会 发 生 多 少 次 , 所 以 Java 语 言 编 译 器 允 许 Java 程 序 不 对 它进 行
处 理 。

    除 此 之 外 的 其 他 例 外 则 被 称 为 非 运 行时 例 外 。



图 20.1 例 外 处 理 — — 类 的 层 次 

    用 户 自 己 定 义 的 例 外 都 是 非 运 行 时 例外 。 然 而 并
非 所 有 非 运 行 时 例 外 都 是 用 户 自 己 定 义 的 例外 。

    所 谓 用 户 自 己 定 义 的 例 外 , 就 是 你 在编 写 程 序 的
时 候 在 你 的 程 序 里 面 定 义 的 那 些 例 外 , 以 便使 得 你 的 程 序 具 有 更 高 的 可 靠
性 , 不 会 轻 易 地 出 差 错 。

    Java 编 译 器 要 求 必 须 捕 获 或 声 明 所 有 的非 运 行 时
例 外 。 对 于 用 户 自 定 义 例 外 , 这 是 十 分 显 然 的; 否 则 , 系 统 就 不 知 道 这 些
用 户 自 定 义 的 例 外 的 特 性 。知 己 知 彼 才 能 百 战 百 胜 。


简 单 的 例 外 处 理 

    运 行 时 例 外 的 处 理

    先 看 看 下 面 这 两 个 例 子 。

程 序 20.1

public class REP{

  public static void main(String args[ ]) {

    int AE = 1/0; // AE 等 于 1 除 以 0 , 将 导 致除 0
溢 出 例 外


    }

  }

程 序 20.2

public class REP{

  public static void main(String args[ ]) {

    int i = 0;

    int AE = 1/i; // AE 等 于 1 除 以 i , 而 i 等于 0
, 也 将 导 致 除 0 溢 出


    }

  } 

    在 程 序 20.1 和 程 序 20.2 中 都 出 现 了 除 数为 0 导
致 的 “ 除 0 溢 出 ” 例 外 , 这 属 于 运 行 时 例 外 。 此 时, 运 行 程 序 的 系 统 会 自
动 把 生 成 的 例 外 对 象 交 给 缺 省 的( 也 就 是 默 认 的 ) 例 外 处 理 程 序 , 在 计 算
机 屏 幕 上 显 示出 这 个 例 外 的 内 容 及 发 生 此 例 外 的 位 置 。 在 JDK 环 境 下 运行
这 两 个 例 子 程 序 。 ( 有 关 JDK 开 发 环 境 的 介 绍 请 参 见 《开 发 环 境 》 一 章 )

    程 序 20.1 的 运 行 结 果 为 :

    c:\java\exam >javac REP.java

    REP.java:3: Arithmetic exception.

        int AE = 1/0;

            ^

    1 error

    可 见 , 程 序 在 编 译 的 时 候 编 译 器 就 指出 了 错 误 。
此 程 序 不 能 通 过 编 译 。 无 法 生 成 可 以 运 行 的文 件 。

    程 序 20.2 的 运 行 结 果 是 :

    c:\java\exam>javac REP.java

    c:\java\exam>java REP

    java.lang.ArithmeticException: / by zero

        at REP.main(REP.java:4)

    程 序 20.2 虽 然 通 过 了 编 译 , 编 译 器 没 有指 出 有 错
误 , 从 而 生 成 了 可 以 运 行 的 程 序 文 件 , 但 是 该程 序 在 运 行 时 系 统 指 出 出 现
了 例 外 。

非 运 行 时 例 外

    我 们 也 是 先 看 一 个 例 子 :

程 序 20.3

class MyE extends Exception{ // 定 义 一 个 例 外 类
MyE


    private int detailA,detailB;

    MyE(int a,int b){

        detailA = a;

        detailB = b;

        }

    public String toString(){

        return "MyException : "+detailA+"<"+detailB;

        }

    }

 public class ED{ // 定 义 一 个 类 ED

static void compare(int a,int b) throws MyE {

    System.out.println("***************************");

    System.out.println("call compare("+a+","+b+")");

    if (a

         throw new MyE(a,b);

    System.out.println("normal exit : "+a+">
= "+b);


    }

 static void callcompare(int a,int b){

    try{

        compare(a,b);

      } catch(MyE e){

            System.out.println("Catch "+e);

                }

        finally{

            System.out.println("return from
callcompare()");


            }

    }

 public static void main (String args[ ]){

        callcompare(10,5);

        callcompare(5,5);

        callcompare(5,10);

        }

}

    程 序 20.3 抛 弃 了 自 己 的 例 外 。 上 例 对 两个 整 数 a
和 b 进 行 了 比 较 ( compare ) , 当 a ( = b 时 程 序 正常 运 行 , 当 a((b 时
程 序 抛 弃 例 外 MyException 。 


 


 

在 JDK 里 例 20.3 的 运 行 结 果 如 下 :

    c:\java\exam>java ED

    ***************************

    call compare(10,5)

    normal exit : 10> = 5

    return from callcompare()

    ***************************

    call compare(5,5)

    normal exit : 5> = 5

    return from callcompare()

    ***************************

    call compare(5,10)

    Catch MyException : 5<10

    return from callcompare() 

例 外 的 抛 弃 、 捕 获 和 声 明 

    除 对 运 行 时 例 外 可 以 不 做 处 理 外 , 例外 处 理 还 有
以 下 几 种 方 法 :


  1. 使 用 throws 子 句 生 命 例 外 ;
  2. 定 义 自 己 的 例 外 类 , 并 用 throw 语 句 来 抛 弃 它;
  3. 使 用 try-catch-finally 语 句 捕 获 例 外 。


抛 弃 例 外

    在 Java 语 言 中 捕 获 一 个 例 外 之 前 , 必 须有 一 段 Java
代 码 生 成 一 个 例 外 对 象 并 把 它 抛 弃 。 抛 弃 例外 的 代 码 可 以 是 你 自 己 Java
的 程 序 , JDK 中 的 某 个 类 , 或者 是 Java 运 行 时 系 统 。 这 就 像 在 蓝 球 场 上
打 球 一 样 , 你 若想 接 到 一 个 球 , 就 必 须 有 人 先 抛 出 这 个 球 , 不 管 这 人 是中
锋 , 还 是 后 卫 , 亦 或 是 对 方 球 员 。 同 理 , 如 同 所 有 人抛 球 都 必 须 用 手 一 样
, 无 论 是 你 自 己 的 程 序 还 是 运 行 时系 统 , 都 必 须 使 用 throw 语 句 来 抛 弃 例
外 。

    例 如 , 在 例 20.3 的 compare 方 法 中 就 使 用了 throw
语 句 来 抛 弃 一 个 例 外 :

     throw new MyE(a,b);

其 中 MyE 是 Exception 的 一 个 子 类 。

 

 

    class MyE extends Exception{ // class MyException
}


由 throw 抛 弃 的 例 外 必 须 是 Throwable 类 或 其 子类 的 对
象 。

声 明 例 外

    在 很 多 情 况 下 , 生 成 例 外 的 方 法 并 不需 要 处 理 它
, 而 是 用 throws 子 句 来 声 明 它 , 以 向 上 传 递 。如 例 20.3 中


    static void compare(int a,int b) throws MyE
{


这 样 就 在 compare 方 法 中 声 明 了 例 外 MyE 。

    一 个 方 法 中 也 可 以 同 时 声 明 多 个 例 外, 只 需 throws
在 后 列 出 所 有 要 声 明 的 例 外 即 可 。 例 如

    static void Proc ( ) throws MyE , ArithmeticException{

    … …

    }

捕 获 例 外

    捕 获 例 外 需 使 用 try-catch-finally 语 句 。

    在 例 20.3 的 callcompare 方 法 中 , try 语 句 在
{} 中 指 定 了 一 段 代 码 , 该 代 码 可 能 会 抛 弃 几 个 例 外 ; 其后 的 catch 用 于
处 理 这 些 例 外 ; finally 则 提 供 了 统 一 的 出口 。

 static void callcompare(int a,int b){

    try{

        compare(a,b);

    }

        catch(MyE e){

            System.out.println("Catch "+e);

            }

        finally{

            System.out.println("return from
callcompare()");


            }

    }

 

程 序 20.4 import java.awt.*;

import java.applet.*;

class MyE extends Exception{ // class MyException

    private int detailA,detailB;

    MyE(int a,int b){

        detailA = a;

        detailB = b;

            }

    public String toString(){

        return "MyException : "+detailA+"<"+detailB;

            }

    

}

class Cons{ // 设 置 一 个 常 数 , 让 它 代 表 两 条线 之 间
的 距 离


    final int jmp = 13;

    }

public class ED extends Applet{ // class Exception
Demo


    static void compare(int a,int b,Graphics g,int
Ln,int col) throws MyE {


      Cons jump = new Cons();

      g.drawString("***************************",col,Ln);

      g.drawString("call compare("+a+","+b+")",col,Ln+jump.jmp);

      if (a

        throw new MyE(a,b);

      g.drawString("normal exit :"+a+">
= "+b,col,Ln+2*jump.jmp);


        }

static void callcompare(int a,int b,Graphics
g,int Ln,int col){


  Cons jump = new Cons();

    try{

        compare(a,b,g,Ln,col);

      }

        catch(MyE e){

        g.drawString("Catch "+e,col,Ln+2*jump.jmp);

            }

      finally{

            g.drawString("return from callcompare()",col,Ln+3*jump.jmp);

            }

    }

public void paint (Graphics g){

    Cons jump = new Cons();

    int Ln;

    int col;

    Ln = 10; col = 20;

    callcompare(10,5,g,Ln,col);

    Ln = Ln+5*jump.jmp;

    callcompare(5,5,g,Ln,col);

    Ln = Ln+5*jump.jmp;

    callcompare(5,10,g,Ln,col);

      }

    }

    程 序 20.4 是 程 序 20.3 的 Applet 形 式 , 它 的运 行
结 果 如 图 20.2 所 示 。




图 20.2 程 序 20.4 的 执 行 结 果

几 件 值 得 注 意 的 事 情


  1. 自 定 义 的 例 外 类 的 类 名 通 常 可 以 以 Exception 结尾
    。 例 如 :


    MyException , MyArithmeticException 等 。
  2. 对 于 运 行 时 例 外 可 以 不 捕 获 、 声 明 , 而 提 交运 行 时
    系 统 处 理 。

  3. 在 捕 获 或 声 明 例 外 时 , 要 选 取 合 适 类 型 与 层次 的 例
    外 。

  4. 处 理 例 外 既 可 以 在 方 法 内 捕 获 并 处 理 , 也 可以 提 交
    上 层 方 法 处 理 。

  5. 使 用 finally 语 句 可 为 例 外 处 理 提 供 统 一 的 出 口,
    通 常 可 在 finally 语 句 中 进 行 资 源 清 除 工 作 , 如 关 闭 已打 开 的 文 件 等 。


小 结


  • Java 采 用 面 向 对 象 的 例 外 处 理 机 制 减 小 了 编 程量
    , 增 加 了 灵 活 性 , 增 强 了 程 序 的 可 读 性 和 可 靠 性 , 有利 于 编 写 具 有 动 态
    运 行 特 性 的 复 杂 程 序 。

  • 对 非 运 行 时 例 外 必 须 捕 获 或 声 明 。

    对 于 自 定 义 的 例 外 类 , 通 常 作 为 类 Exception 的 子
    类 , 而 不 作 为 类 Error 的 子 类 。 因 为 类 Error 通 常 用 于系 统 内 严 重 的 硬
    件 错 误 。

  • 抛 弃 的 例 外 必 须 是 Throwable 类 或 其 子 类 的 对 象。
  • 注 意 区 分 throw 和 throws 的 用 法 :

    throw 用 于 抛 弃 例 外 ;

    throws 用 于 声 明 例 外 。


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· JAVA基础:怎样设计合适的接口 (09-28) · JAVA基础:我个人的面向对象的程序观 (09-28)
· JAVA基础:JSP抓网页代码的程序 (09-27) · Servlet中如何捕获Session事件? (09-27)
· JAVA基础:利用Java实现zip压缩解压缩 (09-25) · JAVA基础:JAVA程序中实现FTP的功能 (09-25)
· 编程:Java能够成为完美的技术平台吗? (09-22) · 模式:Struts—基于MVC设计模式的JSP (09-22)
· 高级:类反射简化Struts应用程序的开发 (09-22) · JAVA编程:新一代Java技术即将出现 (09-22)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
· 中小企业发展缓慢 电子商务存在的问题多
· 马云追加20亿投资淘宝 图谋电子商务霸主
· 国产ITIL运维先行者 四大厂商角力BI市场
· 企业信息安全解决方案 方正电子公文系统
  IT博客 ·曾剑秋·项立刚·Java学习·网管
  IT技术论坛 ·开发·网管·安全·数据库·系统