Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1165758
  • 博文数量: 234
  • 博客积分: 5592
  • 博客等级: 大校
  • 技术积分: 1987
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-23 14:12
文章分类

全部博文(234)

文章存档

2015年(1)

2013年(4)

2012年(16)

2011年(204)

2010年(9)

分类: Java

2011-05-04 17:33:27

1.前言:

你的程序总有一天会崩溃掉,在崩溃掉的时候我们要知道它在哪,为了什么而崩溃掉,数据的保存或者丢

失情况如何等问题。我们可以通过继承类java.lang.Throwable的子类:Exception来设计我们自己的Java异常

。Exception类用于描述程序能够捕获的异常,如ClassNotFoundException。要注意的是自定义异常类之间也

可以有继承关系,同时也需要为自定义异常类设计构造方法,以方便构造自定义异常对象。

2.设计实例分析:

这是个比较完整的自定义异常类的设计,其实是比较模板化的东西。


package playground;
import java.io.*;
public class MyException extends Exception {
private int id; // a unique id
private String classname; // the name of the class
private String method; // the name of the method
private String message; // a detailed message
private MyException previous =
null; // the exception which was caught
private String separator = "\n"; // line separator
public MyException(int id, String classname, String method,
String message, MyException previous) {
this.id = id;
this.classname = classname;
this.method = method;
this.message = message;
this.previous = previous;
}
public String traceBack() {
return traceBack("\n");
}
public String traceBack(String sep) {
this.separator = sep;
int level = 0;
MyException e = this;
String text = line("Calling sequence (top to bottom)");
while (e != null) {
level++;
text += line("--level " + level + "--------------------------------------");
text += line("Class/Method: " + e.classname + "/" + e.method);
text += line("Id : " + e.id);
text += line("Message : " + e.message);
e = e.previous;
}
return text;
}
private String line(String s) {
return s + separator;
}
}

我们来一个个看看这些东西:

在这个继承了Exception类的自定义异常类中,我们定义了如下变量:

id:独立标示符,这个是用来进行标示类中什么地方出现了错误被捕捉到。

classname:捕捉到这个错误的类的名字。

method:捕捉到这个错误的方法的名字。

message:用来描述整个事件的情况。

previous:是MyException得一个实例,若在链表中它是第一个的话,那么它就是null。
我们再看看都定义了什么方法:

traceBack():产生一个包含在异常类中存储的数据的一个回溯。使用newline标示作为分隔符

traceBack(String sep):和上一个其实是相同的东西,使用的分隔符可以自己定义。

line(String s):traceBack使用的一个方法。

步骤一:先扔出第一个异常:

这有两种情况:

a.若程序判断异常的某个地方主动抛出异常,那么你就会主动抛出一个错误,例如:


throw new MyException( 1, "Person", "getSalary",
"Trying to get a salary, but no person was specified",null);

b.在另一个异常出现时抛出该异常,例如:


catch (Exception e) {
throw new MyException(4, "Person", "read", e.toString(), null);
}

要是某一个方法要抛出MyException异常,那么在方法定义的时候形式如下:

public void read() throws MyException . . .

步骤二:接着我们扔出来的异常,例如:


Person p = new Person();
p.setPersonId(id);
try {
p.read();
s += p.getSalary();
}
catch (MyException e) {
throw new MyException(1, "Stats", "getAllSalaries",
"Could not get salary for " + id, e);
}

我们的策略是这样的:将我们可能扔出异常的方法置于我们的监控之下(try{}),然后出了事情我们在处理

区(catch{})把这个异常处理,至于处理的方式可以是当场处理,也可以处理不了交予其他地方处理(throw())。

需要注意的是,我们看到最后一个参数e,我们要在每个新的异常处将这个异常加入到异常类的链表中。

步骤三:回溯异常

我们上边设计的这个异常最后得出的一个异常链如下:


Calling sequence (top to bottom)
--level 1--------------------------------------
Class/Method: SalaryServlet/doGet
Id : 7
Message : Trying to get the total salary for employees
--level 2--------------------------------------
Class/Method: Stats/getAllSalaries
Id : 1
Message : Could not get salary for Lincoln
--level 3--------------------------------------
Class/Method: Person/read
Id : 3
Message : java.sql.SQLException: [HANSEN]Invalid object name 'xEMPLOYEE'.
--level 4--------------------------------------
Class/Method: Person/read
Id : 999
Message : SQLException. State/error code: S0002/208

我们可以分析得知在这个场景上,一个servlet被触发了,它调用了getAllSalaries,然后又调用了read方法

,在read方法中,出现了一个SQLException

3.总结:

自定义异常类给了我们自己喜欢
阅读(830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~