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

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

2016-06-16 16:49 267 查看

java异常

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

自定义异常

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

怎么处理异常?

1、捕获并抛出运行时异常。不能一味的向上抛,如果抛到了用户界面层(或者说main函数),还不处理,那就直接显示给了用户,就不能给用户提供友好界面。异常在向上抛的过程中,也会给调用者带来麻烦,所以还是得处理。可以将异常try/catch,抛出运行时异常,调用者可以处理,也可以不处理。
try{.....
}catch(Exceptione){
thrownewRuntimeException(e);
}
2、编译时异常用作返回值,通知调用者,发生错误。下面是学习jaxp的dom解析方式来解析xml文档时,删除学生时,考虑到学生不存在的情况下,如何处理。若不存在该学生,要通知给调用者,用来通知用户,当然可以通过改变返回值类型来实现,如删除成功则返回true,删除不存在该学生,则返回false。但在不改变返回值类型的情况下,可以通过抛异常来通知调用者,将异常当做一种返回值来处理,同时为了保证能够传递方式某种错误的信息,需要自定义异常,如StudentNotFoundException,若调用者遇到该异常,就可以识别发生了什么错误,并可以给用户友好提示。先看代码:删除学生:
//StudentDao.java
publicvoiddelete(Stringname)throwsStudentNotFoundException{
//获得name标签列表,遍历,若相等,则获取该name标签的父节点的父节点,删除student标签
try{
Documentdocument=XmlUtils.getDocument();//会抛出异常,所以下面找catch
NodeListlist=document.getElementsByTagName("name");
for(inti=0;i<list.getLength();i++){
if(list.item(i).equals(name)){//找到匹配该名字的学生并删除
list.item(0).getParentNode().getParentNode().removeChild(list.item(i).getParentNode());
return;
}
thrownewStudentNotFoundException();
}
}catch(StudentNotFoundExceptione){
	throwe;
}
catch(Exceptione){
	//TODOAuto-generatedcatchblock
	e.printStackTrace();
}
}
调用者:
//main.java...............
System.out.print("请输入学生姓名:");
	Stringname=br.readLine();
	
	StudentDaodao=newStudentDao();
	try{
dao.delete(name);
}catch(StudentNotFoundExceptione){
System.out.println("删除的学生不存在!!!");
e.printStackTrace();
}
..............
可以看到程序抛了StudentNotFoundException异常,又catch,又抛出,到底在搞什么?因为Documentdocument=XmlUtils.getDocument();会抛出异常,所以需要下面catch(Exceptione)来处理异常;我们需要在学生不存在的时候抛出异常来通知调用者,所以抛出了异常(thrownewStudentNotFoundException(););但此时抛出的异常,又被catch(Exceptione)处理掉了,那怎么使StudentNotFoundException异常让调用者catch到呢?catch异常的时候,要先catch小的,在catch大的异常,所谓的小指的是子异常类,大则指父异常类。所以就在catch(Exceptione)前面加了catch(StudentNotFoundExceptione)并把异常抛出去,由于此时该方法在catch中抛出了异常并没有相应的try/catch来处理该异常,则需要声明该方法抛出异常StudentNotFoundException。这样是不是调用者就可以在调用该方法时,发现StudentNotFoundException异常,并可以处理,通知用户。3、实际项目中,可能发生多种多样的异常,通常定义一个包来封装这些自定义的异常类。4、捕获抛出自定义运行时异常。若即想通知调用者发生什么错误,又想给调用者选择权,既可以处理异常又可以不处理异常,则捕获异常,抛出自定义运行时异常(继承RuntimeException类),抛出运行时异常异常的方法也可以不用进行异常声明。下面结合学习jdbc时遇到的问题,结合Service层来讲DAO层异常处理。UserDaoJdbcImpl.java中的addUser方法:
publicvoidaddUser(Useruser){
Connectionconn=null;
PreparedStatementps=null;
ResultSetrs=null;
try{
	conn=JdbcUtils.getConnection();
	Stringsql="insertintouser(name,birthday,money)values(?,?,?)";
	ps=conn.prepareStatement(sql);
	ps.setString(1,user.getName());
	ps.setDate(2,newjava.sql.Date(user.getBirthday().getTime()));
	ps.setFloat(3,user.getMoney());
	ps.executeUpdate();//会出现异常
}catch(SQLExceptione){
	thrownewDaoException(e.getMessage(),e);
}finally{
	JdbcUtils.free(rs,ps,conn);
}
}
在执行ps.executeUpdate()方法时会出现异常,要怎么解决呢?1、跑出异常,但定义的userDao接口中定义addUser方法是没有异常抛出的,java的异常机制可知,子类中的方法只能抛出比父类方法更少的异常,不能更多,所以如果抛出异常,则需要改动接口中的adduser方法,增加抛出异常的声明,但这样就破坏了接口,如果使用herbinate来实现数据userDao接口,而Hibernate来访问数据库时不抛出异常,那么这个接口就不能使用,所以这种方法不可行。2、捕获并处理,良好的程序设计,不能仅仅捕获异常,打印堆栈信息;而是需要给调用者一个良好的提示。比较好的做法是,自定义一个异常类,表示异常类型,抛出给调用者,调用者就知道发生了什么异常。这里是定义了 运行时异常类DaoException,捕获SQLException并抛出 运行时异常类DaoException,这样调用者在调用方法时,若发生了异常,调用者就知道是在dao实现层发生了异常。这样做的好处是,不污染接口;通知调用者,发生了什么错误;同时调用者对异常具有选择性,既可以处理也可以选择不处理,比较灵活。自定义异常类:
packagedao;
 
publicclassDaoExceptionextendsRuntimeException{
 
	privatestaticfinallongserialVersionUID=1L;
 
	publicDaoException(){
//TODOAuto-generatedconstructorstub
}
 
	publicDaoException(Stringmessage){
super(message);
//TODOAuto-generatedconstructorstub
}
 
	publicDaoException(Throwablecause){
super(cause);
//TODOAuto-generatedconstructorstub
}
 
	publicDaoException(Stringmessage,Throwablecause){
super(message,cause);
//TODOAuto-generatedconstructorstub
}
 
}
 
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  异常处理