您的位置:首页 > 编程语言 > Java开发

Java:如何处理异常

2008-04-09 14:57 761 查看
在处理异常时,应该区分checked异常和unchecked异常。对于checked异常,我们应该提供健壮的异常恢复机制,而对于unchecked异常,这就是编程错误即bug,应该在调试阶段很好的发现和处理它们。
1. Java[/b]异常层次结构[/b][/b]



上图(注:该图引自http://dev2dev.bea.com.cn/techdoc/200702364792.html)标出了Java异常层次结构,也指出了哪些异常是unchecked,哪些异常是checked。下面给出几段常见的异常处理代理,试图总结日常开发中应该如何处理异常。
2.[/b]针对[/b]checked[/b]异常的恢复机制[/b][/b]
checked异常并不是编程错误,它的出现是软件运行阶段所不可避免的。最常见的这类异常如socket连接超时。
对于此类异常,我们应该在程序的运行态下试图从异常中恢复过来。下面这段代码(Recover.java)的主要逻辑是,对目标值protected int current进行判断,如果该值大于2则成功,否则抛出NotBigEnoughException异常。
在执行程序的过程中,在每次catch到NotBigEnoughException异常时,我们对current值递增,试图从异常中恢复过来。
NotBigEnoughException.java
[align=left]package com.zj.exception.types;[/align]
[align=left] [/align]
[align=left]public class NotBigEnoughException extends Exception {[/align]
[align=left] public NotBigEnoughException() {[/align]
[align=left] super();[/align]
[align=left] }[/align]
[align=left] [/align]
public NotBigEnoughException(String
msg) {
[align=left] super(msg);[/align]
[align=left] }[/align]
}
Recover.java
[align=left]package com.zj.exception;[/align]
[align=left]import com.zj.exception.types.NotBigEnoughException;[/align]
[align=left] [/align]
[align=left]public class Recover {[/align]
[align=left] protected int current = 0;[/align]
[align=left] protected boolean accept = false;[/align]
[align=left] [/align]
[align=left] public Recover() {}[/align]
[align=left] [/align]
[align=left] public Recover(int cur) {[/align]
[align=left] current = cur;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public void increment() {[/align]
[align=left] ++current;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public boolean passed() {[/align]
[align=left] return accept;[/align]
[align=left] }[/align]
[align=left] [/align]
public void passing() throws
NotBigEnoughException {
[align=left] if (current > 2) {[/align]
[align=left] accept = true;[/align]
[align=left] System.out.println("accept " + current);[/align]
[align=left] } else[/align]
[align=left] throw new NotBigEnoughException("reject " + current);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public static void main(String[] args) {[/align]
[align=left] Recover re = new Recover();[/align]
[align=left] while (!re.passed()) {[/align]
[align=left] try {[/align]
[align=left] re.passing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] System.out.println(e);[/align]
[align=left] re.increment();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
}
结果:
[align=left]com.zj.exception.types.NotBigEnoughException: reject 0[/align]
[align=left]com.zj.exception.types.NotBigEnoughException: reject 1[/align]
[align=left]com.zj.exception.types.NotBigEnoughException: reject 2[/align]
accept 3
3.[/b]继承异常[/b][/b]
在子类继承父类的情况下,子类override方法的异常声明只能取自(小于等于)父类该方法的异常声明;对于子类构造方法的异常声明必须包含(大于等于)父类构造方法的异常声明。
类Inheritor继承自类Recover,它的方法passing()试图声明一个父类没有的异常UnknowException,这样做是不允许的。
UnknowException.java
[align=left]package com.zj.exception.types;[/align]
[align=left] [/align]
[align=left]public class UnknowException extends Exception {[/align]
[align=left] public UnknowException() {[/align]
[align=left] super();[/align]
[align=left] }[/align]
[align=left] [/align]
public UnknowException(String msg)
{
[align=left] super(msg);[/align]
[align=left] }[/align]
}
error in: Inheritor.java
//couldn't
throws new exceptions where not found in its base class
[align=left]public void passing() throws NotBigEnoughException, UnknowException {[/align]
[align=left] if (current > 2) {[/align]
[align=left] accept = true;[/align]
[align=left] System.out.println("accept " + current);[/align]
[align=left] } else if (current >= 0)[/align]
[align=left] throw new NotBigEnoughException("reject " + current);[/align]
[align=left] else[/align]
[align=left] throw new UnknowException("i don't know how to deal with "[/align]
[align=left] + current);[/align]
}
之所以覆盖这个方法的目的是对父类的passing()方法做进一步扩展,对0<=current<=2的情况抛出NotBigEnoughException,而对current<0的情况则抛出一个新的异常UnknowException。
此时,提供两种解决方法。
方法一,使用恢复异常机制,overrding passing()方法,这样可以处理掉所有的异常,因此不需要异常声明。
ok in: Inheritor.java
//sure
passing(),so not have to throw exceptions
[align=left]public void passing(){[/align]
[align=left] while (!passed()) {[/align]
[align=left] try {[/align]
[align=left] super.passing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] increment();[/align]
[align=left] }[/align]
[align=left] }[/align]
}
方法二,写一个加强的passing()方法,即fortifiedPassing(),对于在父类passing()中捕获的异常,进行再判断。如果是0<=current<=2的情况则重新抛出NotBigEnoughException,如果是current<0的情况则抛出一个新的异常UnknowException。
ok in: Inheritor.java
public void fortifiedPassing() throws NotBigEnoughException,
UnknowException{
[align=left] try {[/align]
[align=left] super.passing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] if(current>=0)[/align]
[align=left] throw e;[/align]
[align=left] else[/align]
[align=left] throw new UnknowException("i don't know how to deal with "[/align]
[align=left] + current);[/align]
[align=left] }[/align]
}
Inheritor.java
[align=left]package com.zj.exception;[/align]
[align=left]import com.zj.exception.types.NotBigEnoughException;[/align]
[align=left]import com.zj.exception.types.UnknowException;[/align]
[align=left] [/align]
[align=left]public class Inheritor extends Recover {[/align]
[align=left] public Inheritor(int cur) {[/align]
[align=left] super(cur);[/align]
[align=left] }[/align]
[align=left] [/align]
//couldn't
throws new exceptions where not found in its base class
[align=left] /**[/align]
[align=left] public void passing() throws NotBigEnoughException, UnknowException {[/align]
[align=left] if (current > 2) {[/align]
[align=left] accept = true;[/align]
[align=left] System.out.println("accept " + current);[/align]
[align=left] } else if (current >= 0)[/align]
[align=left] throw new NotBigEnoughException("reject " + current);[/align]
[align=left] else[/align]
[align=left] throw new UnknowException("i don't know how to deal with "[/align]
[align=left] + current);[/align]
[align=left] }*/[/align]
[align=left] [/align]
//sure
passing(),so not have to throw exceptions
[align=left] public void passing(){[/align]
[align=left] while (!passed()) {[/align]
[align=left] try {[/align]
[align=left] super.passing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] increment();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
public void fortifiedPassing() throws
NotBigEnoughException, UnknowException{
[align=left] try {[/align]
[align=left] super.passing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] if(current>=0)[/align]
[align=left] throw e;[/align]
[align=left] else[/align]
[align=left] throw new UnknowException("i don't know how to deal with "[/align]
[align=left] + current);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public static void main(String[] args) {[/align]
[align=left] // not required try-catch[/align]
[align=left] new Inheritor(3).passing();[/align]
[align=left] new Inheritor(1).passing();[/align]
[align=left] new Inheritor(-1).passing(); [/align]
[align=left] //no exceptions[/align]
[align=left] try {[/align]
[align=left] new Inheritor(3).fortifiedPassing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] e.printStackTrace();[/align]
[align=left] } catch (UnknowException e) {[/align]
[align=left] System.out.println(e);[/align]
[align=left] }[/align]
[align=left] //NotBigEnoughException:[/align]
[align=left] try {[/align]
[align=left] new Inheritor(1).fortifiedPassing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] e.printStackTrace();[/align]
[align=left] } catch (UnknowException e) {[/align]
[align=left] System.out.println(e);[/align]
[align=left] }[/align]
[align=left] //UnknownException:[/align]
[align=left] try {[/align]
[align=left] new Inheritor(-1).fortifiedPassing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] e.printStackTrace();[/align]
[align=left] } catch (UnknowException e) {[/align]
[align=left] System.out.println(e);[/align]
[align=left] }[/align]
[align=left] }[/align]
}
结果:
[align=left]accept 3[/align]
[align=left]accept 3[/align]
[align=left]accept 3[/align]
[align=left]accept 3[/align]
[align=left]com.zj.exception.types.UnknowException: i don't know how to deal with -1[/align]
[align=left]com.zj.exception.types.NotBigEnoughException: reject 1[/align]
at
com.zj.exception.Recover.passing(Recover.java:28)
at
com.zj.exception.Inheritor.fortifiedPassing(Inheritor.java:38)
at
com.zj.exception.Inheritor.main(Inheritor.java:63)
4.RuntimeException[/b]与包装异常[/b][/b]
RuntimeException是unhecked异常,它们由JVM抛出(你也可以抛出它),并且不必在异常声明(throws)中列出。
如果RuntimeException没有被catch而到达mian()方法时,那么在程序退出前会自动调用该异常的printStackTrace()方法,打印该异常。
RuntimeException代表的是编程错误(如0除数,数组越界),是应该在调试阶段解决的。
当你在捕获某些异常,而不知道该如果处理时,你可以将它包装为RuntimeException,这样在后续的方法调用过程中就不用声明(throws)该方法了。
在类Wrapper中,我们override fortifiedPassing()方法,并将它可能抛出的异常包装为RuntimeException。
Wrapper.java
[align=left]package com.zj.exception;[/align]
[align=left]import com.zj.exception.types.NotBigEnoughException;[/align]
[align=left]import com.zj.exception.types.UnknowException;[/align]
[align=left] [/align]
[align=left]public class Wrapper extends Inheritor {[/align]
[align=left] public Wrapper(int cur) {[/align]
[align=left] super(cur);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public void fortifiedPassing() {[/align]
[align=left] try {[/align]
[align=left] super.fortifiedPassing();[/align]
[align=left] } catch (NotBigEnoughException e) {[/align]
[align=left] throw new RuntimeException(e);[/align]
[align=left] } catch (UnknowException e) {[/align]
[align=left] throw new RuntimeException(e);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public static void main(String[] args) {[/align]
[align=left] // not required try-catch[/align]
[align=left] new Wrapper(3).fortifiedPassing();[/align]
[align=left] new Wrapper(1).fortifiedPassing();[/align]
[align=left] new Wrapper(-1).fortifiedPassing();[/align]
[align=left] }[/align]
}
结果:
[align=left]accept 3[/align]
Exception in thread
"main" java.lang.RuntimeException: com.zj.exception.types.NotBigEnoughException: reject 1
at
com.zj.exception.Wrapper.fortifiedPassing(Wrapper.java:14)
at
com.zj.exception.Wrapper.main(Wrapper.java:23)
[align=left]Caused by: com.zj.exception.types.NotBigEnoughException: reject 1[/align]
at
com.zj.exception.Recover.passing(Recover.java:28)
at
com.zj.exception.Inheritor.fortifiedPassing(Inheritor.java:38)
at
com.zj.exception.Wrapper.fortifiedPassing(Wrapper.java:12)
... 1
more

附件:http://down.51cto.com/data/2349723
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 职场 异常 休闲
相关文章推荐