ncyu_phyedu 板


LINE

简介 所谓例外(Exception),指的是程式发生不正常的错误,而导致无法继续执行的情形。例外 处理(Exception Handling)顾名思义,就是当例外发生时的处理机制。 C语言里并没有例外处理的机制,使用函数库时,可能会发生无法处理的状况,此时必须由呼 叫者小心检查传回值才行。如果不检查,就会发生无法预期的结果 #include <stdio.h> main() { int data; FILE* f = fopen("sample.txt", "r"); // sample.txt may not exist, fopen returns NULL fscanf(f, "%d", &data); // may result segmentation fault; } 上述例子里,如果档案sample.txt不存在,则无法开启该档案,因此fopen传回NULL。如果不 检查传回值,则会产生segmentation fault。比较好的写法是: #include <stdio.h> main() { int data; FILE* f = fopen("sample.txt", "r"); // sample.txt may not exist, fopen returns NULL if (f == NULL) { printf("Can't open file sample.txt. Please check if it exists and you have privilege to access.\n"); return; } fscanf(f, "%d", &data); // may result segmentation fault; } 又例如sqrt()可以用来求平方根,但如果我们给他负数,sqrt该如何处理?根据手册,sqrt遇 到负数参数,会传回NaN(Not a Number,是浮点数里的一个特别数值)。使用sqrt的函数必 须特别检查该值,否则计算出来的东西都变成了NaN。又例如除法运算时分母是0的情况,严 格说起来也是一种错误,某些系统也会产生floating exception (core dumped)。 没有提供例外处理机制的语言,程式的正确性必须靠极端小心的设计者才行。为了减少程 式错误的机会,让软体很强固(robust),Java提供了例外处理的机制。 相关语法 在Java里,Exception是一个Class。Exception extends Throwable, Throwable extends Object。Exception,Throwable这两个类别均定义於java.lang这个package内。设计者也 可以自订自己的Exception类别。相关的Exception语法如下: 自订Exception类别 public class MyException extends Exception { } 宣告某method会产生例外 import java.io.*; public class ExceptionExample { public void someMethod() throws Exception { // 请注意throws最後面是s // some code may fail FileInputStream f; try { f = new FileInputStream("abc.txt"); // if abc.txt does not exist, FileNotFoundException will be caught } catch(FileNotFoundException fnf) { System.out.println("File not found. Generate an exception and throw it"); throw fnf; // 注意throw後面没有s // throw new Exception(); // or you can throw a new Exception object } } public static void main(String[] argv) { ExceptionExample s = new ExceptionExample(); try { s.someMethod(); } catch(Exception epp) { System.out.println("An Exception has been caught."); } } } 拦截exception的语法 try { } catch (TypeOneException e1) { } catch (TypeTwoException e2) { } catch (TypeThreeException e3) { } finally { } try {} catch{}类似像if then else if的结构。当try {}里面某一行指令产生Exception 时,try区块会立刻中断执行,然後到第一个catch判断抓到的Exception是否instanceof TypeOneException,如果是则执行该catch区块;如果不是,则进一步比较instanceof TypeTwoException。也就是说虽然可以写很多个catch区块,但执行时最多只有一块会执行 到。离开try或catch区块以前,如果有finally区块,则finally区块一定会被执行到。一般 来说finally区块里面的程式码大多用来作资源回收,或清理资料结构的工作,以确保不论 有无发生状况,程式都能继续正常执行。 try { System.out.println("Opening FileInputStream"); FileInputStream f = new FileInputStream("abc.txt"); // assume this operation generate FileNotFoundException System.out.println("File Opened"); } catch (FileNotFoundException e1) { System.out.println("FileNotFoundException caught"); } catch (Exception e2) { System.out.println("Exception caught"); } finally { System.out.println("Execute finally block"); } 上述的范例会印出 Opening FileInputStream FileNotFoundException caught Execute finally block 如果把上面例子稍微改一下: try { System.out.println("Opening FileInputStream"); FileInputStream f = new FileInputStream("abc.txt"); // assume this operation generate FileNotFoundException System.out.println("File Opened"); } catch (Exception e2) { System.out.println("Exception caught"); } catch (FileNotFoundException e1) { System.out.println("FileNotFoundException caught"); } finally { System.out.println("Execute finally block"); } 则聪明一点的Compiler会抱怨FileNotFoundException的区块unreachable(执行不到)。这 是因为FileNotFoundException是Exception的子类别,因此如果产生的例外是instanceof Exception,则FileNotFoundException就不会执行了;若产生的例外不是instanceof Exception,那就更不会执行到FileNotFoundException区块了。 是否所有的Exception都要处理? 原则上是的。只要用到的method有宣告throws SomeException,则呼叫该method的地方,就 要使用try {} catch(SomeException)的语法。当然像是try {} catch(SuperClassOfSomeException)的用法也行。唯一的例外是 java.lang.RuntimeException及其子类别可以不必处理。 哪些属於RuntimeException呢?像是ArrayIndexOutOfBoundException就是其中之一,它发 生在阵列索引不合法的情况下: public class Test { public static void main(String[] argv) { int[] x = new int[10]; x[100] = 0; // will generate ArrayIndexOutOfBoundException } } exception产生时,JVM会由堆叠追踪此错误点的呼叫资讯,并一一向外检查,直到有try catch区块拦截此exception为止。在上述的例子中,没有任何try catch的宣告,则JVM会终 止该执行绪。 类别Exception的相关方法 抓到例外後,可透过该例外物件,得到有趣的资讯 toString()以简单的字串描述该例外 getMessage()列出细节讯息 printStackTrace()将堆叠资讯印在萤幕上,可帮助设计者快速找到错误点 Error 前面提到Exception是Throwable的子类别。另一个Throwable的子类别是java.lang.Error 。所谓Error指的是严重的错误情况。当Error产生时,其行为和Exceptio类似,但是try catch区块没有办法拦下它们,最後会由JVM来处理Error,并中断执行绪的执行。像 OutOfMemoryError,StackOverflowError都是Error的子类别。 范例 用Link List实作Stack public class Stack { private Node head; private int size; class Node { Object data; Node next; } public void push(Object s) { Node tmp = new Node(); tmp.next = head; tmp.data = s; size++; head = tmp; } public Object pop() throws Exception { if (head == null) { throw new Exception(); } Object tmp = head.data; head = head.next; size--; return tmp; } } public class Example { public static void main(String[] argv) { Stack s1 = new Stack(); Stack s2 = new Stack(); s1.push("abc"); s1.push("def"); s2.push("123"); s2.push("456"); try { s1.pop(); } catch(Exception e) {} } } public class Example2 { public static void main(String[] argv) throws Exception { Stack s1 = new Stack(); Stack s2 = new Stack(); s1.push("abc"); s1.push("def"); s2.push("123"); s2.push("456"); s1.pop(); } } 用Link List实作Queue public class Queue { private Node head, tail; private int size; class Node { Object data; Node next; } public void put(Object s) { Node tmp = new Node(); tmp.data = s; if (tail != null) { tail.next = tmp; } else { head = tmp; } tail = tmp; size++; } public Object get() throws Exception { if (head == null) { throw new Exception(); } Object tmp = head.data; head = head.next; if (head == null) { tail = null; } size--; return tmp; } } --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.58.22.74







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP