java异常处理三——怎么处理异常

java异常


几个需要注意到点:
1、finally语句:为异常处理提供了一个统一的出口,无论程序是否发生异常,都会执行,所以通常用来进行资源清理的工作,如关闭文件,清理数据库连连接,删除临时文件等;
2、重写方法抛出异常与原方法所抛出异常类型一致,或者不抛出异常,不能抛多抛少,抛的范围大或小。
3、子类方法不能比父类方法抛出更多的异常。
4、一个try块可以对应多个catch块,在catch异常时,要先捕获小的,再捕获大的;否则小的异常会被前面 catch块 捕获。

自定义异常

通过继承java.lang.Exception类来自定义异常。

怎么处理异常?

1、捕获并抛出运行时异常。不能一味的向上抛,如果抛到了用户界面层(或者说main函数),还不处理,那就直接显示给了用户,就不能给用户提供友好界面。异常在向上抛的过程中,也会给调用者带来麻烦,所以还是得处理。可以将异常try/catch,抛出运行时异常,调用者可以处理,也可以不处理。
   
   
try{.....
}catch (Exception e) {
throw new RuntimeException(e);
}
2、编译时异常用作返回值,通知调用者,发生错误。
下面是学习jaxp的dom解析方式来解析xml文档时,删除学生时,考虑到学生不存在的情况下,如何处理。 若不存在该学生,要通知给调用者,用来通知用户,当然可以通过改变返回值类型来实现,如删除成功则返回true,删除不存在该学生,则返回false。但在不改变返回值类型的情况下,可以 通过抛异常来通知调用者,将异常当做一种返回值来处理,同时为了保证能够传递方式某种 错误的信息,需要自定义异常,如StudentNotFoundException,若调用者遇 到该异常,就可以识别发生了什么错误,并可以给用户友好提示。先看代码:

删除学生:
   
   
//StudentDao.java
public void delete(String name) throws StudentNotFoundException{
//获得name标签列表,遍历,若相等,则获取该name标签的父节点的父节点,删除student标签
try {
Document document = XmlUtils.getDocument();//会抛出异常,所以下面找catch
NodeList list = document.getElementsByTagName("name");
for (int i = 0; i < list.getLength(); i++) {
if (list.item(i).equals(name)) {//找到匹配该名字的学生并删除
list.item(0).getParentNode().getParentNode().removeChild(list.item(i).getParentNode());
return;
}
throw new StudentNotFoundException();
}
}catch(StudentNotFoundException e){
throw e;
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
调用者:
    
    
//main.java
...............
System.out.print("请输入学生姓名:");
String name = br.readLine();
StudentDao dao = new StudentDao();
try {
dao.delete(name);
} catch (StudentNotFoundException e) {
System.out.println("删除的学生不存在!!!");
e.printStackTrace();
}
..............

可以看到程序抛了StudentNotFoundException异常,又catch,又抛出,到底在搞什么?
因为Document document = XmlUtils.getDocument(); 会抛出异常,所以需要下面catch (Exception e)来处理异常;
我们需要在学生不存在的时候抛出异常来通知调用者,所以抛出了异常(throw new StudentNotFoundException(); ) ;
但此时抛出的异常,又被catch (Exception e)处理掉了,那怎么使StudentNotFoundException异常让调用者catch到呢?
catch异常的时候,要先catch小的,在catch大的异常,所谓的小指的是子异常类,大则指父异常类。所以就在catch (Exception e)前面加了catch(StudentNotFoundException e)并把异常抛出去,由于此时该方法在catch中抛出了异常并没有相应的try/catch来处理该异常,则需要声明该方法抛出异常StudentNotFoundException。这样是不是调用者就可以在调用该方法时,发现StudentNotFoundException异常,并可以处理,通知用户。

3、实际项目中,可能发生多种多样的异常,通常定义一个包来封装这些自定义的异常类。
4、捕获抛出自定义运行时异常。
若即想通知调用者发生什么错误,又想给调用者选择权,既可以处理异常又可以不处理异常,则捕获异常,抛出自定义运行时异常(继承 RuntimeException类),抛出 运行时异常 异常的方法也可以不用进行异常声明。
下面结合学习jdbc时遇到的问题, 结合Service层来讲 DAO层异常处理。
UserDaoJdbcImpl.java中的addUser方法:
    
    
public void addUser(User user) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "insert into user(name,birthday, money) values (?,?,?) ";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setDate(2, new java.sql.Date(user.getBirthday().getTime()));
ps.setFloat(3, user.getMoney());
ps.executeUpdate();//会出现异常
} catch (SQLException e) {
throw new DaoException(e.getMessage(), e);
} finally {
JdbcUtils.free(rs, ps, conn);
}
}
在执行 ps . executeUpdate ()方法时会出现异常,要怎么解决呢?
1、跑出异常,但定义的userDao接口中定义addUser方法是没有异常抛出的,java的异常机制可知,子类中的方法只能抛出比父类方法更少的异常,不能更多,所以如果抛出异常,则需要改动接口中的adduser方法,增加抛出异常的声明,但这样就破坏了接口,如果使用herbinate来实现数据userDao接口,而 Hibernate来访问数据库时不抛出异常,那么这个接口就不能使用,所以这种方法 不可行。
2、捕获并处理,良好的程序设计,不能仅仅捕获异常,打印堆栈信息;而是需要给调用者一个良好的提示。比较好的做法是,自定义一个异常类,表示异常类型,抛出给调用者,调用者就知道发生了什么异常。这里是定义了  运行时异常类 DaoException ,捕获 SQLException并抛出   运行时异常类 DaoException,这样调用者在调用方法时,若发生了异常,调用者就知道是在dao实现层发生了异常。这样做的好处是,不污染接口;通知调用者,发生了什么错误;同时调用者对异常具有选择性,既可以处理也可以选择不处理,比较灵活。
自定义异常类:
    
    
package dao;
 
public class DaoException extends RuntimeException {
 
private static final long serialVersionUID = 1L;
 
public DaoException() {
// TODO Auto-generated constructor stub
}
 
public DaoException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
 
public DaoException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
 
public DaoException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
 
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值